summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2014-03-10 21:45:01 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-03-10 21:45:01 +0000
commit6466f2cf5c834b0b20b67010c7d88a5b080b7bdc (patch)
tree692580c33ff11dd96e405d07662f6c05d0c37642
parentdd7dafee94f064b00f0d3e30b87c7dfa234f16c6 (diff)
parent869f44d03c83dbaf7429b1c8c2ff82f33920dedf (diff)
downloadidea-6466f2cf5c834b0b20b67010c7d88a5b080b7bdc.tar.gz
Merge "Merge remote-tracking branch 'aosp/snapshot-master' into merge"
-rw-r--r--.idea/libraries/Netty.xml4
-rw-r--r--.idea/modules.xml2
-rw-r--r--bin/win/runnerw.exebin99328 -> 106088 bytes
-rw-r--r--build/scripts/layouts.gant22
-rw-r--r--community-main.iml3
-rw-r--r--community-resources/src/idea_community_about.pngbin110330 -> 73624 bytes
-rw-r--r--community-resources/src/idea_community_about@2x.pngbin220411 -> 213528 bytes
-rw-r--r--community-resources/src/idea_community_logo.pngbin166540 -> 119885 bytes
-rw-r--r--community-resources/src/idea_community_logo@2x.pngbin469101 -> 354398 bytes
-rw-r--r--images/src/org/intellij/images/index/ImageInfoIndex.java10
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/impl/StateCache.java7
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java14
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerCache.java14
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/make/BackwardDependenciesStorage.java6
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/make/Cache.java11
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/make/CompilerDependencyStorage.java6
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java1
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java15
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java8
-rw-r--r--java/compiler/impl/src/com/intellij/openapi/compiler/generic/DummyPersistentState.java7
-rw-r--r--java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFilePersistentState.java7
-rw-r--r--java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileSetState.java6
-rw-r--r--java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileWithDependenciesState.java6
-rw-r--r--java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.java7
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java10
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java116
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java18
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java9
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java3
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/ToggleLineBreakpointActionHandler.java163
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java26
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java11
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java133
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/requests/LocatableEventRequestor.java9
-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/DebuggerContextImpl.java11
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java39
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java21
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java26
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java228
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java81
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java64
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java15
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java17
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddWildcardBreakpointDialog.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java9
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java65
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java385
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java81
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java800
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java322
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java412
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java103
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java94
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java56
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java155
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java127
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java39
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java253
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestorImpl.java243
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java184
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.java (renamed from java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointPropertiesPanel.java)21
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java75
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java138
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java166
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.java92
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java157
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java122
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java107
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java43
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java66
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java77
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java84
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java50
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java79
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java122
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java10
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java3
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java5
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java12
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java4
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java19
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java29
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java87
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapter.java157
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapterBase.java6
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.form (renamed from java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointPropertiesPanel.form)2
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java (renamed from java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointPropertiesPanel.java)20
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java76
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java (renamed from java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointProperties.java)31
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaExceptionBreakpointProperties.java57
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaFieldBreakpointProperties.java57
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaLineBreakpointProperties.java22
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaMethodBreakpointProperties.java58
-rw-r--r--java/debugger/openapi/src/com/intellij/debugger/PositionManagerEx.java26
-rw-r--r--java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java3
-rw-r--r--java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java12
-rw-r--r--java/debugger/openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java2
-rw-r--r--java/idea-ui/src/com/intellij/ide/impl/ProjectStructureSelectInTarget.java17
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java5
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java4
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java39
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java27
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java24
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java2
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java12
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java51
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java56
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java190
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java16
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java7
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java36
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToCatchFix.java17
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java16
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java5
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java5
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java25
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseColorIntentionAction.java39
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/ColorChooserIntentionAction.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java28
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java18
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java6
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.java20
-rw-r--r--java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java24
-rw-r--r--java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.java8
-rw-r--r--java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassProcessor.java16
-rw-r--r--java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/ReplaceWithSubtypeUsageInfo.java19
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.java12
-rw-r--r--java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java9
-rw-r--r--java/java-impl/src/com/intellij/util/xml/CanonicalPsiTypeConverterImpl.java5
-rw-r--r--java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaSourceFilterScope.java21
-rw-r--r--java/java-psi-api/src/com/intellij/psi/GenericsUtil.java8
-rw-r--r--java/java-psi-api/src/com/intellij/psi/LambdaUtil.java12
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiArrayType.java27
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java6
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiClassType.java21
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiDisjunctionType.java21
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java11
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java23
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java69
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java20
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiType.java43
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiWildcardType.java32
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java7
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java18
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java20
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java40
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java136
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java67
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java18
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java44
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java29
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java137
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java13
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java52
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java5
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java14
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.java5
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java45
-rw-r--r--java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping.java4
-rw-r--r--java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping_after.java4
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/UnsupportedFeatures7.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondMisc.java14
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java1
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/LiftedCaptureToOuterCall.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCallsSameMethod.java40
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SiteSubstitutionForReturnConstraint.java21
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeAmbiguity.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java6
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java1
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/StaticProblems.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/Varargs.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsInReceiverPosition.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/DiamondInLambdaReturn.java9
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA118965.java37
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialApplicability.java4
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/ReturnTypeCheckForRawReceiver.java15
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/StaticNonStaticReferenceTypeAmbiguity.java15
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/LambdaFormalParamTypesParametrization.java10
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/NonWildcardParametrization.java108
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/PrimitiveParameterTypes.java13
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterEnumConstantWithoutClassInitializer.java14
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterIDEA108454.java17
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeEnumConstantWithoutClassInitializer.java5
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeIDEA108454.java12
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayList.java15
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListAndFilter.java15
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListLambda.java15
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSet.java15
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSetFieldInitializer.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectLinkedHashSet.java15
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSelfCollection.java15
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSetParameter.java15
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterNoBraces.java10
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterNormalNoBraces.java10
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayList.java17
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListAndFilter.java19
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListLambda.java17
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSet.java17
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSetFieldInitializer.java17
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectLinkedHashSet.java17
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSelfCollection.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSetParameter.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFilterNoBraces.java12
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeNormalNoBraces.java10
-rw-r--r--java/java-tests/testData/codeInsight/gotosuper/Lambda.after.java9
-rw-r--r--java/java-tests/testData/codeInsight/gotosuper/Lambda.java9
-rw-r--r--java/java-tests/testData/codeInsight/gotosuper/LambdaMarker.java9
-rw-r--r--java/java-tests/testData/fileEditorManager/src/Bar.java5
-rw-r--r--java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef.java11
-rw-r--r--java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef_after.java5
-rw-r--r--java/java-tests/testData/psi/shortenClassRefs/pkg/TA.java6
-rw-r--r--java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java2
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java10
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/ImplementMethodsTest.java9
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy51
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy27
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java5
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java2
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalTypeWildcardParameterizationTest.java48
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java10
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java8
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java8
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/navigation/JavaGotoSuperTest.java52
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy77
-rw-r--r--java/java-tests/testSrc/com/intellij/find/FindManagerTest.java2
-rw-r--r--java/java-tests/testSrc/com/intellij/index/IndexTest.java5
-rw-r--r--java/java-tests/testSrc/com/intellij/index/StringIndex.java17
-rw-r--r--java/java-tests/testSrc/com/intellij/openapi/editor/impl/JavaFileEditorManagerTest.java54
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java46
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterNewLineTest.java24
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/ShortenClassReferencesTest.java3
-rw-r--r--java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java320
-rw-r--r--java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java9
-rw-r--r--java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java12
-rw-r--r--java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java5
-rw-r--r--jps/jps-builders/jps-builders.iml1
-rw-r--r--jps/jps-builders/src/META-INF/services/org.jetbrains.jps.builders.java.JavaCompilingTool2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/ModuleChunk.java15
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/EclipseCompilerTool.java94
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/JavacCompilerTool.java82
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/CannotCreateJavaCompilerException.java25
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java18
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaCompilingTool.java58
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java6
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/FieldRepr.java7
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntIntPersistentMultiMaplet.java6
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectPersistentMultiMaplet.java6
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java7
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ObjectObjectPersistentMultiMaplet.java6
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/TypeRepr.java7
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java11
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/TObjectIntHashMapExternalizer.java7
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/storage/ClassFilesIndexStorageBase.java4
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/impl/EnumeratedMethodIncompleteSignature.java4
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java18
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactOutputToSourceMapping.java7
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java78
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/messages/CompilerMessage.java9
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/storage/FileKeyDescriptor.java7
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/storage/OneToManyPathsMapping.java6
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/storage/TimestampStorage.java6
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java70
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java19
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java27
-rw-r--r--jps/model-impl/jps-model-impl.iml2
-rw-r--r--jps/model-impl/jps-model-tests.iml14
-rw-r--r--jps/model-serialization/jps-model-serialization.iml3
-rw-r--r--jps/model-serialization/jps-serialization-tests.iml14
-rw-r--r--lib/netty-all-5.0.0.Alpha2.jar (renamed from lib/netty-all-5.0.0.Alpha1.jar)bin1576326 -> 1631257 bytes
-rw-r--r--lib/required_for_dist.txt2
-rw-r--r--lib/src/netty-all-5.0.0.Alpha2-sources.jar (renamed from lib/src/netty-all-5.0.0.Alpha1-sources.jar)bin1376606 -> 1429360 bytes
-rw-r--r--native/runner/runnerw/runnerw.vcxproj2
-rwxr-xr-xplatform/bootstrap/src/com/intellij/idea/Main.java53
-rw-r--r--platform/core-api/src/com/intellij/openapi/editor/colors/CodeInsightColors.java6
-rw-r--r--platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java4
-rw-r--r--platform/core-api/src/com/intellij/openapi/module/Module.java12
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java17
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/encoding/EncodingRegistry.java5
-rw-r--r--platform/core-api/src/com/intellij/psi/CommonClassNames.java1
-rw-r--r--platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java3
-rw-r--r--platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java16
-rw-r--r--platform/core-api/src/com/intellij/testFramework/LightVirtualFile.java3
-rw-r--r--platform/core-api/src/com/intellij/util/PlatformUtilsCore.java2
-rw-r--r--platform/core-impl/src/com/intellij/openapi/editor/ex/util/SegmentArray.java35
-rw-r--r--platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java66
-rw-r--r--platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java17
-rw-r--r--platform/core-impl/src/com/intellij/openapi/module/impl/ModuleScopeProvider.java13
-rw-r--r--platform/core-impl/src/com/intellij/openapi/vfs/impl/jar/CoreJarVirtualFile.java9
-rw-r--r--platform/core-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandlerBase.java3
-rw-r--r--platform/core-impl/src/com/intellij/openapi/vfs/local/CoreLocalVirtualFile.java3
-rw-r--r--platform/dvcs/src/com/intellij/dvcs/DvcsCommitAdditionalComponent.java77
-rw-r--r--platform/dvcs/testFramework/com/intellij/dvcs/test/MockVirtualFile.java13
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java11
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java8
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java16
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/CaretState.java54
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/event/CaretAdapter.java (renamed from platform/editor-ui-api/src/com/intellij/openapi/editor/event/MultipleCaretListener.java)27
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/event/CaretListener.java14
-rw-r--r--platform/editor-ui-ex/src/com/intellij/injected/editor/MarkupModelWindow.java2
-rw-r--r--platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/MarkupModelEx.java2
-rw-r--r--platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/EmptyMarkupModel.java2
-rw-r--r--platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java4
-rw-r--r--platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java11
-rw-r--r--platform/icons/src/nodes/pluginJB.pngbin0 -> 459 bytes
-rw-r--r--platform/icons/src/nodes/pluginJB@2x.pngbin0 -> 1428 bytes
-rw-r--r--platform/icons/src/nodes/pluginJB@2x_dark.pngbin0 -> 1690 bytes
-rw-r--r--platform/icons/src/nodes/pluginJB_dark.pngbin0 -> 680 bytes
-rw-r--r--platform/icons/src/nodes/pluginRestart.pngbin0 -> 481 bytes
-rw-r--r--platform/icons/src/nodes/pluginRestart@2x.pngbin0 -> 1845 bytes
-rw-r--r--platform/icons/src/nodes/pluginRestart@2x_dark.pngbin0 -> 1804 bytes
-rw-r--r--platform/icons/src/nodes/pluginRestart_dark.pngbin0 -> 634 bytes
-rw-r--r--platform/icons/src/nodes/pluginUpdate.pngbin0 -> 420 bytes
-rw-r--r--platform/icons/src/nodes/pluginUpdate@2x.pngbin0 -> 1241 bytes
-rw-r--r--platform/icons/src/nodes/pluginUpdate@2x_dark.pngbin0 -> 1232 bytes
-rw-r--r--platform/icons/src/nodes/pluginUpdate_dark.pngbin0 -> 571 bytes
-rw-r--r--platform/indexing-api/src/com/intellij/util/indexing/DefaultFileTypeSpecificInputFilter.java4
-rw-r--r--platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java6
-rw-r--r--platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java11
-rw-r--r--platform/indexing-impl/src/com/intellij/openapi/module/impl/ModuleScopeProviderImpl.java36
-rw-r--r--platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java4
-rw-r--r--platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java11
-rw-r--r--platform/indexing-impl/src/com/intellij/psi/search/FileTypeIndex.java23
-rw-r--r--platform/indexing-impl/src/com/intellij/psi/search/FilenameIndex.java6
-rw-r--r--platform/indexing-impl/src/com/intellij/util/indexing/ScalarIndexExtension.java8
-rw-r--r--platform/indexing-impl/src/com/intellij/util/indexing/SingleEntryFileBasedIndexExtension.java3
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/colors/ClickNavigator.java8
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/colors/SimpleEditorPreview.java5
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java26
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java6
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java22
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java21
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/BaseIndentEnterHandler.java30
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java39
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java10
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlighter.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java21
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java9
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java9
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupTypedHandler.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/IncrementalSearchHandler.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java14
-rw-r--r--platform/lang-impl/src/com/intellij/execution/actions/StopProcessAction.java22
-rw-r--r--platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java32
-rw-r--r--platform/lang-impl/src/com/intellij/execution/console/ConsoleGutterComponent.java116
-rw-r--r--platform/lang-impl/src/com/intellij/execution/console/ConsoleIconGutterComponent.java98
-rw-r--r--platform/lang-impl/src/com/intellij/execution/console/GutterContentProvider.java6
-rw-r--r--platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleBuilder.java26
-rw-r--r--platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java96
-rw-r--r--platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java27
-rw-r--r--platform/lang-impl/src/com/intellij/find/FindUtil.java5
-rw-r--r--platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.java17
-rw-r--r--platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java2
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java394
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java400
-rw-r--r--platform/lang-impl/src/com/intellij/find/ngrams/TrigramIndex.java8
-rw-r--r--platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java2
-rw-r--r--platform/lang-impl/src/com/intellij/framework/detection/impl/DetectedFrameworksData.java6
-rw-r--r--platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionIndex.java4
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/SaveAsAction.java4
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java3
-rw-r--r--platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java2
-rw-r--r--platform/lang-impl/src/com/intellij/ide/scratch/CreateScratchFileAction.java149
-rw-r--r--platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadFileSystem.java112
-rw-r--r--platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManager.java35
-rw-r--r--platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java77
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/PlatformPackageUtil.java14
-rw-r--r--platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java32
-rw-r--r--platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java5
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/diff/impl/settings/DiffPreviewPanel.java12
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectAllOccurrencesAction.java80
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectNextOccurrenceAction.java66
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectOccurrencesActionHandler.java88
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/actions/UnselectPreviousOccurrenceAction.java (renamed from platform/lang-impl/src/com/intellij/openapi/editor/actions/UnselectLastOccurrenceAction.java)11
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeFactory.java5
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java30
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/file/exclude/PersistentFileSetManager.java4
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java10
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/vcs/checkin/TodoCheckinHandlerWorker.java4
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeIndex.java15
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java20
-rw-r--r--platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java33
-rw-r--r--platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java14
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java2
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/changeSignature/MethodSignatureEditor.java9
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java4
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesHandler.java7
-rw-r--r--platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java3
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.java6
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/ChangeTrackingValueContainer.java7
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/CustomImplementationFileBasedIndexExtension.java4
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java50
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexProjectHandler.java7
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.java21
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java7
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java48
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java39
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java43
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java17
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java11
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.java12
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/ValueContainer.java12
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java8
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java34
-rw-r--r--platform/lang-impl/src/com/intellij/webcore/packaging/InstalledPackagesPanel.java4
-rw-r--r--platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java5
-rw-r--r--platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java4
-rw-r--r--platform/platform-api/src/com/intellij/ide/caches/CacheUpdater.java8
-rw-r--r--platform/platform-api/src/com/intellij/lang/LanguageDialect.java4
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java11
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java5
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java9
-rw-r--r--platform/platform-api/src/com/intellij/openapi/diff/SimpleContent.java15
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java94
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java27
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedAction.java13
-rw-r--r--platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java19
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/Messages.java36
-rw-r--r--platform/platform-api/src/com/intellij/openapi/vfs/newvfs/impl/StubVirtualFile.java18
-rw-r--r--platform/platform-api/src/com/intellij/openapi/wm/IdeGlassPaneUtil.java8
-rw-r--r--platform/platform-api/src/com/intellij/util/Alarm.java6
-rw-r--r--platform/platform-api/src/com/intellij/util/ui/Animator.java5
-rw-r--r--platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java4
-rw-r--r--platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java3
-rw-r--r--platform/platform-impl/src/com/intellij/designer/model/Property.java4
-rw-r--r--platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java4
-rw-r--r--platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java3
-rw-r--r--platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java7
-rw-r--r--platform/platform-impl/src/com/intellij/ide/dnd/FileCopyPasteUtil.java4
-rw-r--r--platform/platform-impl/src/com/intellij/ide/impl/SelectInEditorManagerImpl.java10
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/PluginHeaderPanel.java7
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java17
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java4
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties3
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonUI.java4
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaToggleButtonUI.java26
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties3
-rw-r--r--platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java8
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/actions/DiffPanelComboBoxAction.java94
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/actions/HighlightModeAction.java85
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java72
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/CurrentLineMarker.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java25
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/FragmentedDiffPanelState.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/PresetBlocksDiffPolicy.java22
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeList.java18
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java7
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/PreferWholeLines.java38
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java38
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/DividerPolygon.java15
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java86
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/actions/CutAction.java7
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretLeftOrRightHandler.java8
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java187
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java82
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java42
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java25
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java23
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/IterationState.java143
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java42
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java8
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java8
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java49
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorState.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java22
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java11
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/VirtualFileImpl.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java1
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FakeVirtualFile.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FileNameCache.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileImpl.java18
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java15
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java7
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java41
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java9
-rw-r--r--platform/platform-impl/src/com/intellij/remote/MutableRemoteCredentials.java45
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteCancelledException.java10
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java170
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteCredentials.java47
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteCredentialsHolder.java260
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteFile.java110
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteProcessHandlerBase.java20
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkAdditionalData.java (renamed from platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkAdditionalData2.java)14
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentials.java11
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsBuilder.java (renamed from platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentialsBuilder.java)2
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java (renamed from platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentialsHolder.java)78
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkException.java49
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkFactory.java (renamed from platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkFactory2.java)7
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkProducer.java (renamed from platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkProducer.java)5
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java (renamed from platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkProperties.java)6
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java (renamed from platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkPropertiesHolder.java)45
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSshProcess.java22
-rw-r--r--platform/platform-impl/src/com/intellij/remote/VagrantBasedCredentialsHolder.java51
-rw-r--r--platform/platform-impl/src/com/intellij/remote/WebDeploymentCredentialsHolder.java62
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/MutableRemoteCredentials.java28
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteCancelledException.java19
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentials.java31
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentialsHolder.java205
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteFile.java114
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteInterpreterException.java58
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteProcessHandlerBase.java31
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkAdditionalData.java2
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentials.java7
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkData.java26
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataBuilder.java26
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataHolder.java30
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkFactory.java2
-rw-r--r--platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java33
-rw-r--r--platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java3
-rw-r--r--platform/platform-impl/src/com/intellij/ui/FinderRecursivePanel.java3
-rw-r--r--platform/platform-impl/src/com/intellij/ui/SystemNotifications.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ui/SystemNotificationsImpl.java10
-rwxr-xr-xplatform/platform-impl/src/com/intellij/ui/messages/SheetController.java75
-rwxr-xr-xplatform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java25
-rw-r--r--platform/platform-impl/src/org/jetbrains/ide/BuiltInServerManagerImpl.java13
-rw-r--r--platform/platform-resources-en/src/messages/ActionsBundle.properties11
-rw-r--r--platform/platform-resources-en/src/messages/DiffBundle.properties11
-rw-r--r--platform/platform-resources-en/src/messages/FindBundle.properties4
-rw-r--r--platform/platform-resources-en/src/misc/registry.properties3
-rw-r--r--platform/platform-resources/src/DefaultColorSchemesManager.xml14
-rw-r--r--platform/platform-resources/src/META-INF/LangExtensions.xml5
-rw-r--r--platform/platform-resources/src/META-INF/PlatformExtensions.xml2
-rw-r--r--platform/platform-resources/src/brokenPlugins.txt5
-rw-r--r--platform/platform-resources/src/componentSets/Editor.xml4
-rw-r--r--platform/platform-resources/src/idea/Keymap_Default.xml6
-rw-r--r--platform/platform-resources/src/idea/Keymap_Eclipse.xml5
-rw-r--r--platform/platform-resources/src/idea/Keymap_Mac.xml14
-rw-r--r--platform/platform-resources/src/idea/Keymap_MacClassic.xml10
-rw-r--r--platform/platform-resources/src/idea/LangActions.xml17
-rw-r--r--platform/platform-resources/src/idea/PlatformActions.xml3
-rw-r--r--platform/platform-tests/platform-tests.iml1
-rw-r--r--platform/platform-tests/testSrc/com/intellij/history/integration/TestVirtualFile.java7
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/IgnoreWhiteSpaceTest.java9
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/highlighting/UtilTest.java20
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/processing/LineBlocksDiffPolicyTest.java7
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/processing/TextCompareProcessorTest.java4
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretColumnModeTest.java95
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretUndoRedoTest.java30
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/SelectUnselectOccurrenceActionsTest.java30
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/AbstractEditorTest.java18
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/IterationStateTest.java170
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTest.java44
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTestCase.java40
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/EnforcedPlaintTextFileTypeManagerTest.java39
-rw-r--r--platform/platform-tests/testSrc/com/intellij/remotesdk/RemoteFileTest.java2
-rw-r--r--platform/platform-tests/testSrc/com/intellij/util/io/PersistentMapTest.java20
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java4
-rw-r--r--platform/projectModel-impl/src/com/intellij/core/CoreModule.java12
-rw-r--r--platform/projectModel-impl/src/com/intellij/core/CoreModuleScopeProvider.java13
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java14
-rw-r--r--platform/remote-servers/impl/resources/resources/cloud.properties2
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.form33
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java222
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudSupportConfigurableBase.java154
-rw-r--r--platform/structure-view-api/src/com/intellij/ide/structureView/TextEditorBasedStructureViewModel.java4
-rw-r--r--platform/testFramework/src/com/intellij/mock/Mock.java3
-rw-r--r--platform/testFramework/src/com/intellij/mock/MockModule.java24
-rw-r--r--platform/testFramework/src/com/intellij/mock/MockVirtualFile.java4
-rw-r--r--platform/testFramework/src/com/intellij/mock/MockVirtualFileSystem.java5
-rw-r--r--platform/testFramework/src/com/intellij/psi/formatter/FormatterTestCase.java (renamed from platform/testFramework/testSrc/com/intellij/psi/formatter/FormatterTestCase.java)0
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java14
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java10
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java8
-rw-r--r--platform/util/src/com/intellij/icons/AllIcons.java3
-rw-r--r--platform/util/src/com/intellij/openapi/diff/LineTokenizer.java78
-rw-r--r--platform/util/src/com/intellij/openapi/diff/LineTokenizerBase.java100
-rw-r--r--platform/util/src/com/intellij/openapi/diff/ex/DiffFragment.java117
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/ComparisonPolicy.java260
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/DiffFragmentBuilder.java44
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/fragments/LineFragment.java9
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/highlighting/FragmentSide.java26
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/highlighting/Util.java144
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/processing/ByWord.java109
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/processing/DiffCorrection.java55
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/processing/DiffPolicy.java37
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/processing/Formatting.java10
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/processing/LineFragmentsCollector.java23
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/processing/UniteSameType.java15
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/processing/Word.java42
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/string/DiffString.java420
-rw-r--r--platform/util/src/com/intellij/openapi/diff/impl/string/DiffStringBuilder.java82
-rw-r--r--platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java12
-rw-r--r--platform/util/src/com/intellij/openapi/util/Key.java3
-rw-r--r--platform/util/src/com/intellij/util/LocalTimeCounter.java10
-rw-r--r--platform/util/src/com/intellij/util/diff/PatienceIntLCS.java2
-rw-r--r--platform/util/src/com/intellij/util/io/DataExternalizer.java8
-rw-r--r--platform/util/src/com/intellij/util/io/EnumeratorStringDescriptor.java6
-rw-r--r--platform/util/src/com/intellij/util/io/ExternalIntegerKeyDescriptor.java8
-rw-r--r--platform/util/src/com/intellij/util/io/InlineKeyDescriptor.java8
-rw-r--r--platform/util/src/com/intellij/util/io/MappedFileInputStream.java16
-rw-r--r--platform/util/src/com/intellij/util/io/NullableDataExternalizer.java7
-rw-r--r--platform/util/src/com/intellij/util/ui/UIUtil.java27
-rw-r--r--platform/util/src/com/intellij/util/xmlb/TextBinding.java1
-rw-r--r--platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java25
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java31
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/TextPatchBuilder.java45
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/vfs/AbstractVcsVirtualFile.java19
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java2
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java12
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogHashMap.java6
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java7
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java1
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java7
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java2
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/frame/XStackFrame.java3
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/stepping/PsiBackedSmartStepIntoVariant.java2
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java25
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java16
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java41
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java27
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/AddToWatchesAction.java5
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateAction.java5
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateInConsoleAction.java31
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/QuickEvaluateAction.java11
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ResumeAction.java4
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ShowExecutionPointAction.java3
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/SmartStepIntoAction.java5
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActionBase.java5
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerSuspendedActionHandler.java4
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java12
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerActionHandler.java11
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java19
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java18
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XEvaluateInConsoleFromEditorActionHandler.java86
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XToggleLineBreakpointActionHandler.java46
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java71
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointsFavoriteListProvider.java4
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java11
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java75
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java33
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java8
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultConditionComboBoxPanel.java61
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultLogExpressionComboBoxPanel.java59
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java40
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XDebuggerComboBoxProvider.java37
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java53
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java23
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointTypeGroup.java18
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java57
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java9
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java22
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java16
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/ValueLookupManager.java3
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java3
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java8
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java3
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/EvaluateInConsoleFromTreeAction.java32
-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/EvaluatingExpressionRootNode.java2
-rw-r--r--platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointManagerTest.java15
-rw-r--r--platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestUtil.java25
-rw-r--r--plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataGroupVirtualFile.java5
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml7
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties7
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java22
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ControlFlowUtils.java23
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java89
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ImportUtils.java24
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SideEffectChecker.java4
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/VariableAccessUtils.java44
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/VariableAssignedVisitor.java36
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/SharedThreadLocalRandomInspection.java122
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionBase.java110
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspection.java26
-rw-r--r--plugins/InspectionGadgets/src/inspectionDescriptions/LambdaParameterHidingMemberVariable.html11
-rw-r--r--plugins/InspectionGadgets/src/inspectionDescriptions/SharedThreadLocalRandom.html15
-rw-r--r--plugins/InspectionGadgets/src/inspectionDescriptions/ThreadLocalNotStaticFinal.html1
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/AutoUnboxing.java4
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/expected.xml6
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/naming/method_names_differ_only_by_case/expected.xml10
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java35
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFixTest.java121
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/imports/UnusedImportInspectionTest.java15
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/threading/SharedThreadLocalRandomInspectionTest.java77
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionTest.java48
-rw-r--r--plugins/IntelliLang/src/META-INF/plugin.xml14
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/BaseBracesIntention.java63
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitMultiCatchIntention.java38
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReverseForLoopDirectionIntention.java2
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReverseForLoopDirectionPredicate.java112
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceAssignmentWithPostfixExpressionPredicate.java4
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceableWithOperatorAssignmentPredicate.java6
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ConditionalUtils.java69
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ControlFlowUtils.java296
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/SideEffectChecker.java87
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/VariableAccessUtils.java195
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/VariableAssignedVisitor.java199
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/ReplaceIfWithSwitchIntention.java4
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/MergeIfOrPredicate.java4
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/MergeParallelIfsPredicate.java6
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/BetweenIfAndElse.java10
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse.java10
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse2.java10
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse2_after.java8
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse_after.java8
-rw-r--r--plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/braces/RemoveBracesIntentionTest.java39
-rw-r--r--plugins/ant/jps-plugin/ant-jps-plugin.iml1
-rw-r--r--plugins/ant/src/com/intellij/lang/ant/AntImportsIndex.java4
-rw-r--r--plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/CvsBundle.properties1
-rw-r--r--plugins/cvs/cvs-plugin/src/META-INF/plugin.xml11
-rw-r--r--plugins/devkit/jps-plugin/devkit-jps-plugin.iml1
-rw-r--r--plugins/devkit/src/references/IconsReferencesContributor.java2
-rw-r--r--plugins/eclipse/resources/META-INF/plugin.xml15
-rw-r--r--plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentChecker.java41
-rw-r--r--plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentDetector.java50
-rw-r--r--plugins/git4idea/src/META-INF/plugin.xml13
-rw-r--r--plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java27
-rw-r--r--plugins/git4idea/src/git4idea/history/NewGitUsersComponent.java9
-rw-r--r--plugins/git4idea/src/git4idea/history/wholeTree/GitCommitsSequentialIndex.java7
-rw-r--r--plugins/git4idea/tests/git4idea/tests/SkeletonBuilderTest.java3
-rw-r--r--plugins/github/src/META-INF/plugin.xml12
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java84
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestWorker.java139
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java26
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java86
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java19
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/extensions/GithubCheckoutProvider.java16
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/extensions/GithubHttpAuthDataProvider.java3
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java23
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/ui/GithubBasicLoginDialog.java16
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java44
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java19
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.java42
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthDataHolder.java46
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java36
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/util/GithubUrlUtil.java1
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/util/GithubUtil.java258
-rw-r--r--plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTest.java31
-rw-r--r--plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java8
-rw-r--r--plugins/github/test/org/jetbrains/plugins/github/GithubUrlUtilTest.java43
-rw-r--r--plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java2
-rw-r--r--plugins/google-app-engine/jps-plugin/google-app-engine-jps-plugin.iml1
-rw-r--r--plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java52
-rw-r--r--plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovycOSProcessHandler.java14
-rw-r--r--plugins/groovy/rt-constants/src/org/jetbrains/groovy/compiler/rt/GroovyRtConstants.java1
-rw-r--r--plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/DependentGroovycRunner.java6
-rw-r--r--plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovyCompilerUtil.java46
-rw-r--r--plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java68
-rw-r--r--plugins/groovy/src/META-INF/plugin.xml26
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java9
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateParameterFromUsageFix.java7
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java85
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GrReassignedInClosureLocalVarInspection.java40
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java7
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GroovyUntypedAccessInspection.java61
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java5
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.java9
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java7
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java6
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java5
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java9
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrField.java4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java67
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrAnnotationUtil.java56
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrFieldImpl.java36
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java53
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java7
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.java34
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java146
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionMembersCache.java187
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java3
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightField.java45
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrScriptField.java18
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java6
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java9
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureAsAnonymousParameterEnhancer.java6
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java46
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParamsEnhancer.java144
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/FirstParamHintProcessor.java77
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/FromAbstractTypeMethodsHintProcessor.java57
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/FromStringHintProcessor.java64
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/MapEntryOrKeyValueHintProcessor.java136
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ParamHintProcessor.java84
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/SecondParamHintProcessor.java78
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/SignatureHintProcessor.java77
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/SimpleTypeHintProcessor.java58
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ThirdParamHintProcessor.java78
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.java10
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java28
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java11
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java5
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/util/dynamicMembers/GrDynamicPropertyImpl.java7
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/FastGroovyTestSuite.java4
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy136
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy18
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Gr2_3HighlightingTest.groovy275
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrInspectionTest.groovy27
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/optimizeImports/GroovyAddImportActionTest.groovy32
-rw-r--r--plugins/groovy/testdata/mockGroovyLib2.3/groovy-all-2.3.0.jarbin6666614 -> 6871793 bytes
-rw-r--r--plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties1
-rw-r--r--plugins/hg4idea/src/META-INF/plugin.xml12
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java85
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java15
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAction.java61
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchAbstractAction.java36
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java145
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java20
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommonBranchActions.java129
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java15
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagFromLogAction.java7
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java96
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java7
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPushAction.java14
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgRunConflictResolverAction.java36
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java36
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBookmarkCommand.java65
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBookmarkCreateCommand.java45
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBranchesCommand.java (renamed from plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTagBranchCommand.java)45
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/command/HgMergeCommand.java17
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/command/HgPushCommand.java23
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTagBranch.java52
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java19
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgHeadMerger.java7
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java8
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java6
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCommonDialogWithChoices.form (renamed from plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateToDialog.form)14
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCommonDialogWithChoices.java148
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgMergeDialog.form139
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgMergeDialog.java176
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPullDialog.java18
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPushDialog.form97
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPushDialog.java76
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgRepositorySelectorComponent.java45
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgRunConflictResolverDialog.java17
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgTagDialog.java11
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateToDialog.java129
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/util/HgBranchesAndTags.java62
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUiUtil.java89
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java22
-rw-r--r--plugins/javaFX/FxBuilderEmbedder/FxBuilderEmbedder.iml1
-rw-r--r--plugins/javaFX/FxBuilderEmbedder/lib/embedder.jarbin6644 -> 12111 bytes
-rw-r--r--plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java158
-rw-r--r--plugins/javaFX/javaFX-CE/src/META-INF/plugin.xml14
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/FxmlDataExternalizer.java5
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxControllerClassIndex.java4
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxCustomComponentsIndex.java3
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxIdsIndex.java3
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditorProvider.java2
-rw-r--r--plugins/junit/src/META-INF/plugin.xml13
-rw-r--r--plugins/maven/jps-plugin/maven-jps-plugin.iml1
-rw-r--r--plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java3
-rw-r--r--plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java3
-rw-r--r--plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java9
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/GenerateManagedDependencyAction.java6
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndex.java6
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java4
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java79
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java22
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenMergingUpdateQueue.java4
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/vfs/MavenPropertiesVirtualFile.java17
-rw-r--r--plugins/maven/src/main/resources/META-INF/plugin.xml16
-rw-r--r--plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesFileType.java10
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java23
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/xml/XmlPropertiesIndex.java24
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnLoadedBrachesStorage.java7
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SvnBranchPointsCalculator.java7
-rw-r--r--plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java12
-rw-r--r--plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java11
-rw-r--r--plugins/ui-designer-core/src/META-INF/DesignerCorePlugin.xml (renamed from plugins/ui-designer-core/src/META-INF/plugin.xml)12
-rw-r--r--plugins/ui-designer-core/src/com/intellij/designer/DesignerEditor.java6
-rw-r--r--plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/DragTracker.java27
-rw-r--r--plugins/ui-designer-core/src/com/intellij/designer/model/MetaManager.java20
-rw-r--r--plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsInstrumenter.java9
-rw-r--r--plugins/ui-designer/jps-plugin/ui-designer-jps-plugin.iml1
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassIndex.java4
-rw-r--r--plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java5
-rw-r--r--plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltStackFrame.java2
-rw-r--r--python/helpers/pycharm_generator_utils/constants.py2
-rw-r--r--python/helpers/pycharm_generator_utils/module_redeclarator.py22
-rw-r--r--python/helpers/pydev/pydevd.py2
-rw-r--r--python/helpers/pydev/pydevd_breakpoints.py3
-rw-r--r--python/helpers/pydev/pydevd_comm.py8
-rw-r--r--python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java26
-rw-r--r--python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java86
-rw-r--r--python/ide/src/com/jetbrains/python/configuration/PyConfigurableInterpreterList.java53
-rw-r--r--python/ide/src/com/jetbrains/python/configuration/PyRemovedSdkService.java66
-rw-r--r--python/ide/src/com/jetbrains/python/configuration/PythonContentEntriesConfigurable.java5
-rw-r--r--python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java93
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java2
-rw-r--r--python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java10
-rw-r--r--python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java10
-rw-r--r--python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaPackageType.java3
-rw-r--r--python/psi-api/src/com/jetbrains/python/PythonFileType.java23
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/Callable.java20
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/PyArgumentList.java8
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/PyClass.java8
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/impl/PyTypeProvider.java5
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java13
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/types/PyType.java3
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java8
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java77
-rw-r--r--python/resources/icons/com/jetbrains/python/skeleton.pngbin512 -> 0 bytes
-rw-r--r--python/resources/icons/com/jetbrains/python/skeleton@2x.pngbin1352 -> 0 bytes
-rw-r--r--python/resources/icons/com/jetbrains/python/templateRoot.pngbin195 -> 115 bytes
-rw-r--r--python/src/META-INF/python-core.xml2
-rw-r--r--python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java2
-rw-r--r--python/src/com/jetbrains/pyqt/PyQtTypeProvider.java8
-rw-r--r--python/src/com/jetbrains/python/codeInsight/PyMethodNameTypedHandler.java5
-rw-r--r--python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java2
-rw-r--r--python/src/com/jetbrains/python/codeInsight/intentions/PyDictConstructorToLiteralFormIntention.java2
-rw-r--r--python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java2
-rw-r--r--python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java4
-rw-r--r--python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java2
-rw-r--r--python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsTypeProvider.java9
-rw-r--r--python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.form24
-rw-r--r--python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java21
-rw-r--r--python/src/com/jetbrains/python/configuration/TemplatesConfigurationsModel.java33
-rw-r--r--python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java8
-rw-r--r--python/src/com/jetbrains/python/console/PydevConsoleRunner.java4
-rw-r--r--python/src/com/jetbrains/python/console/RunPythonConsoleAction.java2
-rw-r--r--python/src/com/jetbrains/python/debugger/PyDebugProcess.java2
-rw-r--r--python/src/com/jetbrains/python/debugger/PySmartStepIntoHandler.java5
-rw-r--r--python/src/com/jetbrains/python/debugger/PyStackFrame.java2
-rw-r--r--python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java2
-rw-r--r--python/src/com/jetbrains/python/findUsages/PyFindUsagesHandlerFactory.java2
-rw-r--r--python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java2
-rw-r--r--python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java2
-rw-r--r--python/src/com/jetbrains/python/inspections/PyByteLiteralInspection.java2
-rw-r--r--python/src/com/jetbrains/python/inspections/PyComparisonWithNoneInspection.java2
-rw-r--r--python/src/com/jetbrains/python/inspections/PyInitNewSignatureInspection.java2
-rw-r--r--python/src/com/jetbrains/python/inspections/PyMandatoryEncodingInspection.java2
-rw-r--r--python/src/com/jetbrains/python/inspections/PyMethodMayBeStaticInspection.java10
-rw-r--r--python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java2
-rw-r--r--python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java16
-rw-r--r--python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java4
-rw-r--r--python/src/com/jetbrains/python/inspections/PyProtectedMemberInspection.java5
-rw-r--r--python/src/com/jetbrains/python/inspections/PySetFunctionToLiteralInspection.java18
-rw-r--r--python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java4
-rw-r--r--python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java2
-rw-r--r--python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java2
-rw-r--r--python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java2
-rw-r--r--python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java4
-rw-r--r--python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java2
-rw-r--r--python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java18
-rw-r--r--python/src/com/jetbrains/python/packaging/ui/PyInstalledPackagesPanel.java10
-rw-r--r--python/src/com/jetbrains/python/psi/PyUtil.java5
-rw-r--r--python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java2
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyArgumentListImpl.java17
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyBinaryExpressionImpl.java2
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java38
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java16
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyClassImpl.java21
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java2
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java127
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java21
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java2
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyPrefixExpressionImpl.java2
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java2
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java10
-rw-r--r--python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java2
-rw-r--r--python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java2
-rw-r--r--python/src/com/jetbrains/python/psi/stubs/PyModuleNameIndex.java2
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java10
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java14
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyFunctionType.java12
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyGenericType.java2
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java2
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyModuleType.java2
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyNoneType.java2
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyTupleType.java2
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyTypeChecker.java40
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyUnionType.java5
-rw-r--r--python/src/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureHandler.java2
-rw-r--r--python/src/com/jetbrains/python/refactoring/classes/DependencyVisitor.java17
-rw-r--r--python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java6
-rw-r--r--python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java58
-rw-r--r--python/src/com/jetbrains/python/refactoring/classes/membersManager/FieldsManager.java16
-rw-r--r--python/src/com/jetbrains/python/refactoring/classes/membersManager/InstanceFieldsManager.java13
-rw-r--r--python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java37
-rw-r--r--python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java41
-rw-r--r--python/src/com/jetbrains/python/refactoring/classes/membersManager/NamelessFilter.java21
-rw-r--r--python/src/com/jetbrains/python/refactoring/classes/membersManager/PropertiesManager.java210
-rw-r--r--python/src/com/jetbrains/python/refactoring/classes/membersManager/PyRecursiveElementVisitorWithResult.java19
-rw-r--r--python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java2
-rw-r--r--python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java4
-rw-r--r--python/src/com/jetbrains/python/remote/PyRemoteSdkCredentials.java2
-rw-r--r--python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java23
-rw-r--r--python/src/com/jetbrains/python/remote/RemoteDebuggableProcessHandler.java2
-rw-r--r--python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java2
-rw-r--r--python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.form81
-rw-r--r--python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java115
-rw-r--r--python/src/com/jetbrains/python/sdk/PySdkUtil.java5
-rw-r--r--python/src/com/jetbrains/python/sdk/PythonSdkAdditionalData.java27
-rw-r--r--python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java15
-rw-r--r--python/src/com/jetbrains/python/sdk/PythonSdkType.java58
-rw-r--r--python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java78
-rw-r--r--python/src/com/jetbrains/python/sdk/flavors/MacPythonSdkFlavor.java25
-rw-r--r--python/src/com/jetbrains/python/sdk/flavors/PyRemoteSdkFlavor.java2
-rw-r--r--python/src/com/jetbrains/python/sdk/flavors/UnixPythonSdkFlavor.java20
-rw-r--r--python/src/com/jetbrains/python/sdk/flavors/VirtualEnvSdkFlavor.java2
-rw-r--r--python/src/com/jetbrains/python/sdk/flavors/WinPythonSdkFlavor.java6
-rw-r--r--python/src/com/jetbrains/python/validation/PyAnnotatingVisitor.java15
-rw-r--r--python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java61
-rw-r--r--python/src/icons/PythonIcons.java1
-rw-r--r--python/testData/refactoring/extractsuperclass/properties.after.py27
-rw-r--r--python/testData/refactoring/extractsuperclass/properties.before.py22
-rw-r--r--python/testData/refactoring/pullup/presenter/file.py26
-rw-r--r--python/testData/refactoring/pullup/properties/Class.after.py19
-rw-r--r--python/testData/refactoring/pullup/properties/Class.py25
-rw-r--r--python/testData/refactoring/pullup/properties/SuperClass.after.py15
-rw-r--r--python/testData/refactoring/pullup/properties/SuperClass.py3
-rw-r--r--python/testData/refactoring/pullup/pyPullUpInfoModel.py45
-rw-r--r--python/testSrc/com/jetbrains/python/PyEncodingTest.java9
-rw-r--r--python/testSrc/com/jetbrains/python/PyTypeParserTest.java4
-rw-r--r--python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java5
-rw-r--r--python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpInfoModelTest.java21
-rw-r--r--python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java4
-rw-r--r--python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpTest.java7
-rw-r--r--resources-en/src/messages/DebuggerBundle.properties10
-rw-r--r--resources/src/META-INF/IdeaPlugin.xml17
-rw-r--r--spellchecker/src/com/intellij/spellchecker/english.dic1
-rwxr-xr-xupdater/src/com/intellij/updater/Runner.java45
-rw-r--r--updater/testSrc/com/intellij/updater/DigesterTest.java2
-rw-r--r--updater/testSrc/com/intellij/updater/RunnerTest.java2
-rw-r--r--updater/testSrc/com/intellij/updater/UpdaterTestCase.java2
-rw-r--r--xml/dom-impl/src/com/intellij/util/xml/DomFileIndex.java4
-rw-r--r--xml/dom-impl/src/com/intellij/util/xml/impl/DomApplicationComponent.java6
-rw-r--r--xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionData.java5
-rw-r--r--xml/impl/src/com/intellij/codeInsight/editorActions/HtmlSelectioner.java5
-rw-r--r--xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java36
-rw-r--r--xml/impl/src/com/intellij/codeInsight/editorActions/XmlGtTypedHandler.java41
-rw-r--r--xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java10
-rw-r--r--xml/impl/src/com/intellij/html/index/Html5CustomAttributesIndex.java6
-rw-r--r--xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java5
-rw-r--r--xml/impl/src/com/intellij/xml/index/SchemaTypeInheritanceIndex.java7
-rw-r--r--xml/impl/src/com/intellij/xml/index/XmlTagNamesIndex.java3
-rw-r--r--xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java19
-rw-r--r--xml/tests/src/com/intellij/codeInsight/completion/XmlTypedHandlersTest.java66
-rw-r--r--xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java28
-rw-r--r--xml/xml-psi-impl/src/com/intellij/lang/html/HtmlParsing.java5
-rw-r--r--xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java29
-rw-r--r--xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java6
-rw-r--r--xml/xml-psi-impl/src/com/intellij/xml/index/XmlIndex.java6
-rw-r--r--xml/xml-psi-impl/src/com/intellij/xml/index/XmlNamespaceIndex.java7
1069 files changed, 20597 insertions, 12054 deletions
diff --git a/.idea/libraries/Netty.xml b/.idea/libraries/Netty.xml
index 8037545021dc..bc6600b3242d 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-5.0.0.Alpha1.jar!/" />
+ <root url="jar://$PROJECT_DIR$/lib/netty-all-5.0.0.Alpha2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
- <root url="jar://$PROJECT_DIR$/lib/src/netty-all-5.0.0.Alpha1-sources.jar!/" />
+ <root url="jar://$PROJECT_DIR$/lib/src/netty-all-5.0.0.Alpha2-sources.jar!/" />
</SOURCES>
</library>
</component> \ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 350f82e1c2fe..3da23322cd48 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -113,6 +113,8 @@
<module fileurl="file://$PROJECT_DIR$/jps/model-api/jps-model-api.iml" filepath="$PROJECT_DIR$/jps/model-api/jps-model-api.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/jps/model-impl/jps-model-impl.iml" filepath="$PROJECT_DIR$/jps/model-impl/jps-model-impl.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/jps/model-serialization/jps-model-serialization.iml" filepath="$PROJECT_DIR$/jps/model-serialization/jps-model-serialization.iml" group="jps" />
+ <module fileurl="file://$PROJECT_DIR$/jps/model-impl/jps-model-tests.iml" filepath="$PROJECT_DIR$/jps/model-impl/jps-model-tests.iml" />
+ <module fileurl="file://$PROJECT_DIR$/jps/model-serialization/jps-serialization-tests.iml" filepath="$PROJECT_DIR$/jps/model-serialization/jps-serialization-tests.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/jps/standalone-builder/jps-standalone-builder.iml" filepath="$PROJECT_DIR$/jps/standalone-builder/jps-standalone-builder.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/java/jsp-base-openapi/jsp-base-openapi.iml" filepath="$PROJECT_DIR$/java/jsp-base-openapi/jsp-base-openapi.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/java/jsp-openapi/jsp-openapi.iml" filepath="$PROJECT_DIR$/java/jsp-openapi/jsp-openapi.iml" group="java" />
diff --git a/bin/win/runnerw.exe b/bin/win/runnerw.exe
index affd133776f7..5c5f103adca8 100644
--- a/bin/win/runnerw.exe
+++ b/bin/win/runnerw.exe
Binary files differ
diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant
index 4210c5cb90d1..c60b71cb5785 100644
--- a/build/scripts/layouts.gant
+++ b/build/scripts/layouts.gant
@@ -256,7 +256,7 @@ public def layoutCommunityPlugins(String home) {
layoutCloud()
dir("plugins") {
- def simplePlugins = ["commander", "copyright", "java-i18n", "hg4idea", "github", "ui-designer-core"] //, "tasks-time-tracking"]
+ def simplePlugins = ["commander", "copyright", "java-i18n", "hg4idea", "github"] //, "tasks-time-tracking"]
simplePlugins.each {
layoutPlugin it
@@ -710,9 +710,19 @@ def layoutAndroid() {
}
}
- layoutPlugin("android-designer") {
- jar("android-designer.jar") {
- module("android-designer")
+ dir("android-designer") {
+ dir("lib") {
+ jar("resources_en.jar") {
+ module("ui-designer-core") {
+ patternset(refid: "resources.included")
+ }
+ }
+ jar("android-designer.jar") {
+ module("ui-designer-core") {
+ patternset(refid: "resources.excluded")
+ }
+ module("android-designer")
+ }
}
}
}
@@ -818,8 +828,8 @@ def layoutCommunityJps(String home, String target) {
dir("test") {
jar("jps-build-test.jar") {
moduleTests("jps-builders")
- moduleTests("jps-model-impl")
- moduleTests("jps-model-serialization")
+ moduleTests("jps-model-tests")
+ moduleTests("jps-serialization-tests")
}
}
jar("ant-jps-plugin.jar") { module("ant-jps-plugin") }
diff --git a/community-main.iml b/community-main.iml
index c9f5b259e12c..a56cb309b19f 100644
--- a/community-main.iml
+++ b/community-main.iml
@@ -96,6 +96,9 @@
<orderEntry type="module" module-name="manifest" />
<orderEntry type="module" module-name="xml-tests" scope="TEST" />
<orderEntry type="module" module-name="devkit-jps-plugin" scope="TEST" />
+ <orderEntry type="module" module-name="jps-model-tests" scope="TEST" />
+ <orderEntry type="module" module-name="jps-serialization-tests" scope="TEST" />
+ <orderEntry type="module" module-name="ui-designer-jps-plugin" scope="TEST" />
<orderEntry type="module" module-name="ui-designer-jps-plugin" scope="TEST" />
<orderEntry type="module" module-name="java-tests" scope="TEST" />
<orderEntry type="module" module-name="community-tests" scope="TEST" />
diff --git a/community-resources/src/idea_community_about.png b/community-resources/src/idea_community_about.png
index 871356c35677..2b5a763fd9c5 100644
--- a/community-resources/src/idea_community_about.png
+++ b/community-resources/src/idea_community_about.png
Binary files differ
diff --git a/community-resources/src/idea_community_about@2x.png b/community-resources/src/idea_community_about@2x.png
index caf2a3585ae6..f159fb0a2e56 100644
--- a/community-resources/src/idea_community_about@2x.png
+++ b/community-resources/src/idea_community_about@2x.png
Binary files differ
diff --git a/community-resources/src/idea_community_logo.png b/community-resources/src/idea_community_logo.png
index 057bb1673dcf..91a8153fe2dc 100644
--- a/community-resources/src/idea_community_logo.png
+++ b/community-resources/src/idea_community_logo.png
Binary files differ
diff --git a/community-resources/src/idea_community_logo@2x.png b/community-resources/src/idea_community_logo@2x.png
index 451e5f2898e4..1f2cfb1dcceb 100644
--- a/community-resources/src/idea_community_logo@2x.png
+++ b/community-resources/src/idea_community_logo@2x.png
Binary files differ
diff --git a/images/src/org/intellij/images/index/ImageInfoIndex.java b/images/src/org/intellij/images/index/ImageInfoIndex.java
index 28838b5e316d..f2db1b48fc33 100644
--- a/images/src/org/intellij/images/index/ImageInfoIndex.java
+++ b/images/src/org/intellij/images/index/ImageInfoIndex.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.
@@ -46,14 +46,14 @@ public class ImageInfoIndex extends SingleEntryFileBasedIndexExtension<ImageInfo
private final DataExternalizer<ImageInfo> myValueExternalizer = new DataExternalizer<ImageInfo>() {
@Override
- public void save(final DataOutput out, final ImageInfo info) throws IOException {
+ public void save(@NotNull final DataOutput out, final ImageInfo info) throws IOException {
DataInputOutputUtil.writeINT(out, info.width);
DataInputOutputUtil.writeINT(out, info.height);
DataInputOutputUtil.writeINT(out, info.bpp);
}
@Override
- public ImageInfo read(final DataInput in) throws IOException {
+ public ImageInfo read(@NotNull final DataInput in) throws IOException {
return new ImageInfo(DataInputOutputUtil.readINT(in), DataInputOutputUtil.readINT(in), DataInputOutputUtil.readINT(in));
}
};
@@ -83,16 +83,18 @@ public class ImageInfoIndex extends SingleEntryFileBasedIndexExtension<ImageInfo
.fileScope(project, virtualFile));
}
+ @NotNull
@Override
public DataExternalizer<ImageInfo> getValueExternalizer() {
return myValueExternalizer;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new DefaultFileTypeSpecificInputFilter(ImageFileTypeManager.getInstance().getImageFileType()) {
@Override
- public boolean acceptInput(final VirtualFile file) {
+ public boolean acceptInput(@NotNull final VirtualFile file) {
return file.isInLocalFileSystem() &&
file.getLength() / 1024 < ourMaxImageSize
;
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/StateCache.java b/java/compiler/impl/src/com/intellij/compiler/impl/StateCache.java
index bd56b6653b91..631988e17577 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/StateCache.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/StateCache.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,6 +19,7 @@ import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.PersistentHashMap;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
@@ -92,11 +93,11 @@ public abstract class StateCache<T> {
private PersistentHashMap<String, T> createMap(final File file) throws IOException {
return new PersistentHashMap<String,T>(file, new EnumeratorStringDescriptor(), new DataExternalizer<T>() {
- public void save(final DataOutput out, final T value) throws IOException {
+ public void save(@NotNull final DataOutput out, final T value) throws IOException {
StateCache.this.write(value, out);
}
- public T read(final DataInput in) throws IOException {
+ public T read(@NotNull final DataInput in) throws IOException {
return StateCache.this.read(in);
}
});
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
index a20c6975baa8..411fa24b2978 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
@@ -80,7 +80,7 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.TranslatingCompilerFilesMonitor");
- private static final boolean ourDebugMode = false;
+ public static boolean ourDebugMode = false;
private static final FileAttribute ourSourceFileAttribute = new FileAttribute("_make_source_file_info_", 3);
private static final FileAttribute ourOutputFileAttribute = new FileAttribute("_make_output_file_info_", 3);
@@ -89,7 +89,6 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
private final Object myDataLock = new Object();
private final TIntHashSet mySuspendedProjects = new TIntHashSet(); // projectId for all projects that should not be monitored
- private volatile int myWatchedProjectsCount;
private final TIntObjectHashMap<TIntHashSet> mySourcesToRecompile = new TIntObjectHashMap<TIntHashSet>(); // ProjectId->set of source file paths
private PersistentHashMap<Integer, TIntObjectHashMap<Pair<Integer, Integer>>> myOutputRootsStorage; // ProjectId->map[moduleId->Pair(outputDirId, testOutputDirId)]
@@ -196,7 +195,6 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
return;
}
FileUtil.createIfDoesntExist(CompilerPaths.getRebuildMarkerFile(project));
- --myWatchedProjectsCount;
// cleanup internal structures to free memory
mySourcesToRecompile.remove(projectId);
myOutputsToDelete.remove(projectId);
@@ -217,8 +215,8 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
public void watchProject(Project project) {
synchronized (myDataLock) {
- mySuspendedProjects.remove(getProjectId(project));
- ++myWatchedProjectsCount;
+ int projectId = getProjectId(project);
+ mySuspendedProjects.remove(projectId);
}
}
@@ -600,7 +598,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
private void initOutputRootsFile(File rootsFile) throws IOException {
myOutputRootsStorage = new PersistentHashMap<Integer, TIntObjectHashMap<Pair<Integer, Integer>>>(rootsFile, EnumeratorIntegerDescriptor.INSTANCE, new DataExternalizer<TIntObjectHashMap<Pair<Integer, Integer>>>() {
- public void save(DataOutput out, TIntObjectHashMap<Pair<Integer, Integer>> value) throws IOException {
+ public void save(@NotNull DataOutput out, TIntObjectHashMap<Pair<Integer, Integer>> value) throws IOException {
for (final TIntObjectIterator<Pair<Integer, Integer>> it = value.iterator(); it.hasNext();) {
it.advance();
DataInputOutputUtil.writeINT(out, it.key());
@@ -610,7 +608,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
}
}
- public TIntObjectHashMap<Pair<Integer, Integer>> read(DataInput in) throws IOException {
+ public TIntObjectHashMap<Pair<Integer, Integer>> read(@NotNull DataInput in) throws IOException {
final DataInputStream _in = (DataInputStream)in;
final TIntObjectHashMap<Pair<Integer, Integer>> map = new TIntObjectHashMap<Pair<Integer, Integer>>();
while (_in.available() > 0) {
@@ -1476,7 +1474,6 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
}
public void beforeFileDeletion(@NotNull final VirtualFileEvent event) {
- if (myWatchedProjectsCount == 0) return;
final VirtualFile eventFile = event.getFile();
if ((LOG.isDebugEnabled() && eventFile.isDirectory()) || ourDebugMode) {
final String message = "Processing file deletion: " + eventFile.getPresentableUrl();
@@ -1616,7 +1613,6 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
}
private void processNewFile(final VirtualFile file, final boolean notifyServer) {
- if (myWatchedProjectsCount == 0) return;
final Ref<Boolean> isInContent = Ref.create(false);
ApplicationManager.getApplication().runReadAction(new Runnable() {
// need read action to ensure that the project was not disposed during the iteration over the project list
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerCache.java b/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerCache.java
index 5741b9cf7949..4db878623df7 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerCache.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerCache.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.
@@ -112,8 +112,8 @@ public class GenericCompilerCache<Key, SourceState, OutputState> {
}
public static class PersistentStateData<SourceState, OutputState> {
- public final SourceState mySourceState;
- public final OutputState myOutputState;
+ @NotNull public final SourceState mySourceState;
+ @NotNull public final OutputState myOutputState;
private PersistentStateData(@NotNull SourceState sourceState, @NotNull OutputState outputState) {
mySourceState = sourceState;
@@ -139,14 +139,14 @@ public class GenericCompilerCache<Key, SourceState, OutputState> {
}
@Override
- public void save(DataOutput out, KeyAndTargetData<Key> value) throws IOException {
+ public void save(@NotNull DataOutput out, KeyAndTargetData<Key> value) throws IOException {
out.writeInt(value.myTarget);
myKeyDescriptor.save(out, value.myKey);
}
@Override
- public KeyAndTargetData<Key> read(DataInput in) throws IOException {
+ public KeyAndTargetData<Key> read(@NotNull DataInput in) throws IOException {
int target = in.readInt();
final Key item = myKeyDescriptor.read(in);
return getKeyAndTargetData(item, target);
@@ -163,13 +163,13 @@ public class GenericCompilerCache<Key, SourceState, OutputState> {
}
@Override
- public void save(DataOutput out, PersistentStateData<SourceState, OutputState> value) throws IOException {
+ public void save(@NotNull DataOutput out, PersistentStateData<SourceState, OutputState> value) throws IOException {
mySourceStateExternalizer.save(out, value.mySourceState);
myOutputStateExternalizer.save(out, value.myOutputState);
}
@Override
- public PersistentStateData<SourceState, OutputState> read(DataInput in) throws IOException {
+ public PersistentStateData<SourceState, OutputState> read(@NotNull DataInput in) throws IOException {
SourceState sourceState = mySourceStateExternalizer.read(in);
OutputState outputState = myOutputStateExternalizer.read(in);
return new PersistentStateData<SourceState,OutputState>(sourceState, outputState);
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/BackwardDependenciesStorage.java b/java/compiler/impl/src/com/intellij/compiler/make/BackwardDependenciesStorage.java
index fb7a5c6eb280..006debb3b43a 100644
--- a/java/compiler/impl/src/com/intellij/compiler/make/BackwardDependenciesStorage.java
+++ b/java/compiler/impl/src/com/intellij/compiler/make/BackwardDependenciesStorage.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.
@@ -357,7 +357,7 @@ public class BackwardDependenciesStorage implements Flushable, Disposable {
}
private static class MyDataExternalizer implements DataExternalizer<DependenciesSet> {
- public void save(DataOutput out, DependenciesSet ds) throws IOException {
+ public void save(@NotNull DataOutput out, DependenciesSet ds) throws IOException {
final TIntHashSet classes = new TIntHashSet();
final Map<Dependency.FieldRef, TIntHashSet> fieldsMap = new HashMap<Dependency.FieldRef, TIntHashSet>();
final Map<Dependency.MethodRef, TIntHashSet> methodsMap = new HashMap<Dependency.MethodRef, TIntHashSet>();
@@ -414,7 +414,7 @@ public class BackwardDependenciesStorage implements Flushable, Disposable {
}
}
- public DependenciesSet read(DataInput in) throws IOException {
+ public DependenciesSet read(@NotNull DataInput in) throws IOException {
final Set<ReferencerItem> set = new THashSet<ReferencerItem>();
int classesCount = in.readInt();
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/Cache.java b/java/compiler/impl/src/com/intellij/compiler/make/Cache.java
index 2e3d5543214b..f80cb8e5bcaa 100644
--- a/java/compiler/impl/src/com/intellij/compiler/make/Cache.java
+++ b/java/compiler/impl/src/com/intellij/compiler/make/Cache.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.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorIntegerDescriptor;
import com.intellij.util.io.PersistentHashMap;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.DataInput;
@@ -54,10 +55,10 @@ public class Cache {
myStorePath = storePath;
new File(storePath).mkdirs();
myQNameToClassInfoMap = new CachedPersistentHashMap<Integer, ClassInfo>(getOrCreateFile("classes"), EnumeratorIntegerDescriptor.INSTANCE, new DataExternalizer<ClassInfo>() {
- public void save(DataOutput out, ClassInfo value) throws IOException {
+ public void save(@NotNull DataOutput out, ClassInfo value) throws IOException {
value.save(out);
}
- public ClassInfo read(DataInput in) throws IOException {
+ public ClassInfo read(@NotNull DataInput in) throws IOException {
return new ClassInfo(in);
}
}, cacheSize * 2) {
@@ -71,11 +72,11 @@ public class Cache {
myQNameToSubclassesMap = new CompilerDependencyStorage<Integer>(getOrCreateFile("subclasses"), EnumeratorIntegerDescriptor.INSTANCE, cacheSize);
myRemoteQNames = new PersistentHashMap<Integer, Boolean>(getOrCreateFile("remote"), EnumeratorIntegerDescriptor.INSTANCE, new DataExternalizer<Boolean>() {
- public void save(DataOutput out, Boolean value) throws IOException {
+ public void save(@NotNull DataOutput out, Boolean value) throws IOException {
out.writeBoolean(value.booleanValue());
}
- public Boolean read(DataInput in) throws IOException {
+ public Boolean read(@NotNull DataInput in) throws IOException {
return in.readBoolean();
}
}, cacheSize);
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/CompilerDependencyStorage.java b/java/compiler/impl/src/com/intellij/compiler/make/CompilerDependencyStorage.java
index ea93f2193297..2466881b14fd 100644
--- a/java/compiler/impl/src/com/intellij/compiler/make/CompilerDependencyStorage.java
+++ b/java/compiler/impl/src/com/intellij/compiler/make/CompilerDependencyStorage.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,14 +40,14 @@ public class CompilerDependencyStorage<Key> implements Flushable, Disposable {
public CompilerDependencyStorage(File file, KeyDescriptor<Key> keyDescriptor, final int cacheSize) throws IOException {
myMap = new PersistentHashMap<Key, int[]>(file, keyDescriptor, new DataExternalizer<int[]>() {
- public void save(DataOutput out, int[] array) throws IOException {
+ public void save(@NotNull DataOutput out, int[] array) throws IOException {
out.writeInt(array.length);
for (int value : array) {
out.writeInt(value);
}
}
- public int[] read(DataInput in) throws IOException {
+ public int[] read(@NotNull DataInput in) throws IOException {
final TIntHashSet set = new TIntHashSet();
DataInputStream stream = (DataInputStream)in;
while(stream.available() > 0) {
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 13d9be0b5623..506580c351a4 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
@@ -928,6 +928,7 @@ public class BuildManager implements ApplicationComponent{
launcherCp.add(ClasspathBootstrap.getResourcePath(launcherClass));
launcherCp.add(compilerPath);
ClasspathBootstrap.appendJavaCompilerClasspath(launcherCp);
+ launcherCp.addAll(BuildProcessClasspathManager.getLauncherClasspath(project));
cmdLine.addParameter("-classpath");
cmdLine.addParameter(classpathToString(launcherCp));
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java
index 434633f3da47..1da1b5c26631 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java
@@ -27,10 +27,23 @@ import java.util.List;
public abstract class BuildProcessParametersProvider {
public static final ExtensionPointName<BuildProcessParametersProvider> EP_NAME = ExtensionPointName.create("com.intellij.buildProcess.parametersProvider");
+ /**
+ * Override this method to include additional jars to the build process classpath
+ * @return list of paths to additional jars to be included to the build process classpath
+ */
public @NotNull List<String> getClassPath() {
return Collections.emptyList();
}
-
+
+ /**
+ * Override this method to include additional jars to the build process launcher classpath. This may be needed if the plugin provides
+ * custom implementation of Java compiler which must be loaded by the same classloader as tools.jar
+ * @return list of paths to additional jars to be included to the build process launcher classpath
+ */
+ public @NotNull List<String> getLauncherClassPath() {
+ return Collections.emptyList();
+ }
+
public @NotNull List<String> getVMArguments() {
return Collections.emptyList();
}
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java b/java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java
index 2c06c2fb9eeb..5cef06dbab94 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java
@@ -141,4 +141,12 @@ public class BuildProcessClasspathManager {
}
return classpath;
}
+
+ public static List<String> getLauncherClasspath(Project project) {
+ final List<String> classpath = ContainerUtil.newArrayList();
+ for (BuildProcessParametersProvider provider : project.getExtensions(BuildProcessParametersProvider.EP_NAME)) {
+ classpath.addAll(provider.getLauncherClassPath());
+ }
+ return classpath;
+ }
}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/DummyPersistentState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/DummyPersistentState.java
index b3d66ce575fb..495b5a08758f 100644
--- a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/DummyPersistentState.java
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/DummyPersistentState.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.
@@ -16,6 +16,7 @@
package com.intellij.openapi.compiler.generic;
import com.intellij.util.io.DataExternalizer;
+import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
@@ -33,11 +34,11 @@ public class DummyPersistentState {
private static class DummyPersistentStateExternalizer implements DataExternalizer<DummyPersistentState> {
@Override
- public void save(DataOutput out, DummyPersistentState value) throws IOException {
+ public void save(@NotNull DataOutput out, DummyPersistentState value) throws IOException {
}
@Override
- public DummyPersistentState read(DataInput in) throws IOException {
+ public DummyPersistentState read(@NotNull DataInput in) throws IOException {
return INSTANCE;
}
}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFilePersistentState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFilePersistentState.java
index e9ea9700af42..17739b154aa6 100644
--- a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFilePersistentState.java
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFilePersistentState.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.
@@ -16,6 +16,7 @@
package com.intellij.openapi.compiler.generic;
import com.intellij.util.io.DataExternalizer;
+import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
@@ -38,12 +39,12 @@ public class VirtualFilePersistentState {
private static class VirtualFileStateExternalizer implements DataExternalizer<VirtualFilePersistentState> {
@Override
- public void save(DataOutput out, VirtualFilePersistentState value) throws IOException {
+ public void save(@NotNull DataOutput out, VirtualFilePersistentState value) throws IOException {
out.writeLong(value.getSourceTimestamp());
}
@Override
- public VirtualFilePersistentState read(DataInput in) throws IOException {
+ public VirtualFilePersistentState read(@NotNull DataInput in) throws IOException {
return new VirtualFilePersistentState(in.readLong());
}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileSetState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileSetState.java
index a22e80dd77de..cf74b55f6691 100644
--- a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileSetState.java
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileSetState.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.
@@ -67,7 +67,7 @@ public class VirtualFileSetState {
private byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer();
@Override
- public void save(DataOutput out, VirtualFileSetState value) throws IOException {
+ public void save(@NotNull DataOutput out, VirtualFileSetState value) throws IOException {
final Map<String, Long> dependencies = value.myTimestamps;
out.writeInt(dependencies.size());
for (Map.Entry<String, Long> entry : dependencies.entrySet()) {
@@ -77,7 +77,7 @@ public class VirtualFileSetState {
}
@Override
- public VirtualFileSetState read(DataInput in) throws IOException {
+ public VirtualFileSetState read(@NotNull DataInput in) throws IOException {
final VirtualFileSetState state = new VirtualFileSetState();
int size = in.readInt();
while (size-- > 0) {
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileWithDependenciesState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileWithDependenciesState.java
index 9f4a815304de..1b9aee4254a7 100644
--- a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileWithDependenciesState.java
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileWithDependenciesState.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.
@@ -63,7 +63,7 @@ public class VirtualFileWithDependenciesState {
private byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer();
@Override
- public void save(DataOutput out, VirtualFileWithDependenciesState value) throws IOException {
+ public void save(@NotNull DataOutput out, VirtualFileWithDependenciesState value) throws IOException {
out.writeLong(value.mySourceTimestamp);
final Map<String, Long> dependencies = value.myDependencies;
out.writeInt(dependencies.size());
@@ -74,7 +74,7 @@ public class VirtualFileWithDependenciesState {
}
@Override
- public VirtualFileWithDependenciesState read(DataInput in) throws IOException {
+ public VirtualFileWithDependenciesState read(@NotNull DataInput in) throws IOException {
final VirtualFileWithDependenciesState state = new VirtualFileWithDependenciesState(in.readLong());
int size = in.readInt();
while (size-- > 0) {
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.java
index 030e9484ba26..c0a547e817d1 100644
--- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.java
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.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.
@@ -19,6 +19,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.util.SmartList;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.IOUtil;
+import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
@@ -31,7 +32,7 @@ public class ArtifactPackagingItemExternalizer implements DataExternalizer<Artif
private byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer();
@Override
- public void save(DataOutput out, ArtifactPackagingItemOutputState value) throws IOException {
+ public void save(@NotNull DataOutput out, ArtifactPackagingItemOutputState value) throws IOException {
out.writeInt(value.myDestinations.size());
for (Pair<String, Long> pair : value.myDestinations) {
IOUtil.writeUTFFast(myBuffer, out, pair.getFirst());
@@ -40,7 +41,7 @@ public class ArtifactPackagingItemExternalizer implements DataExternalizer<Artif
}
@Override
- public ArtifactPackagingItemOutputState read(DataInput in) throws IOException {
+ public ArtifactPackagingItemOutputState read(@NotNull DataInput in) throws IOException {
int size = in.readInt();
SmartList<Pair<String, Long>> destinations = new SmartList<Pair<String, Long>>();
while (size-- > 0) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java b/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java
index 9ce095c038dc..09be13076ca1 100644
--- a/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java
+++ b/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java
@@ -20,6 +20,9 @@ import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.ui.classFilter.ClassFilter;
+import com.intellij.util.xmlb.annotations.Attribute;
+import com.intellij.util.xmlb.annotations.Tag;
+import com.intellij.util.xmlb.annotations.Transient;
import org.jdom.Element;
/**
@@ -27,10 +30,13 @@ import org.jdom.Element;
* Date: Aug 29, 2003
* Time: 2:49:27 PM
*/
+@Tag("instance-filter")
public class InstanceFilter implements JDOMExternalizable{
public static final InstanceFilter[] EMPTY_ARRAY = new InstanceFilter[0];
-
+
+ @Attribute("id")
public long ID = 0;
+ @Attribute("enabled")
public boolean ENABLED = true;
public InstanceFilter() {
@@ -41,10 +47,12 @@ public class InstanceFilter implements JDOMExternalizable{
this.ENABLED = ENABLED;
}
+ @Transient
public long getId() {
return ID;
}
+ @Transient
public boolean isEnabled() {
return ENABLED;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java
deleted file mode 100644
index 9ed769aee350..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaEditBreakpointActionHandler.java
+++ /dev/null
@@ -1,116 +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.debugger.actions;
-
-import com.intellij.debugger.DebuggerManagerEx;
-import com.intellij.debugger.ui.breakpoints.BreakpointFactory;
-import com.intellij.debugger.ui.breakpoints.BreakpointPropertiesPanel;
-import com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.markup.GutterIconRenderer;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.popup.Balloon;
-import com.intellij.openapi.ui.popup.JBPopupListener;
-import com.intellij.openapi.ui.popup.LightweightWindowEvent;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.wm.IdeFocusManager;
-import com.intellij.util.ui.UIUtil;
-import com.intellij.xdebugger.impl.actions.EditBreakpointActionHandler;
-import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil;
-import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointsDialogFactory;
-import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-import java.awt.*;
-
-public class JavaEditBreakpointActionHandler extends EditBreakpointActionHandler {
- @Override
- protected void doShowPopup(final Project project, final JComponent component, final Point whereToShow, final Object breakpoint) {
- if (!(breakpoint instanceof BreakpointWithHighlighter)) {
- return;
- }
-
- final BreakpointWithHighlighter javaBreakpoint = (BreakpointWithHighlighter)breakpoint;
- BreakpointFactory breakpointFactory = null;
- for (BreakpointFactory factory : BreakpointFactory.EXTENSION_POINT_NAME.getExtensions()) {
- if (factory.getBreakpointCategory().equals(javaBreakpoint.getCategory())) {
- breakpointFactory = factory;
- }
- }
- assert breakpointFactory != null : "can't find factory for breakpoint " + javaBreakpoint;
-
- final BreakpointPropertiesPanel propertiesPanel = breakpointFactory.createBreakpointPropertiesPanel(project, true);
- assert propertiesPanel != null;
- propertiesPanel.initFrom(javaBreakpoint, false);
-
- final JComponent mainPanel = propertiesPanel.getPanel();
- final JBPopupListener saveOnClose = new JBPopupListener.Adapter() {
- @Override
- public void onClosed(LightweightWindowEvent event) {
- propertiesPanel.saveTo(javaBreakpoint);
- propertiesPanel.dispose();
- DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().fireBreakpointChanged(javaBreakpoint);
- }
- };
-
- final Runnable showMoreOptions = new Runnable() {
- @Override
- public void run() {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
- @Override
- public void run() {
- BreakpointsDialogFactory.getInstance(project).showDialog(javaBreakpoint);
- }
- });
- }
- };
-
- final Balloon balloon = DebuggerUIUtil.showBreakpointEditor(project, mainPanel, whereToShow, component, showMoreOptions, breakpoint);
- balloon.addListener(saveOnClose);
-
- propertiesPanel.setDelegate(new BreakpointPropertiesPanel.Delegate() {
- @Override
- public void showActionsPanel() {
- propertiesPanel.setActionsPanelVisible(true);
- balloon.hide();
- DebuggerUIUtil.showBreakpointEditor(project, mainPanel, whereToShow, component, showMoreOptions, breakpoint).addListener(saveOnClose);
- }
- });
-
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- IdeFocusManager.findInstance().requestFocus(mainPanel, true);
- }
- });
- }
-
- @Override
- public boolean isEnabled(@NotNull Project project, AnActionEvent event) {
- DataContext dataContext = event.getDataContext();
- Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
- if (editor == null) {
- return false;
- }
- final Pair<GutterIconRenderer,Object> pair = XBreakpointUtil.findSelectedBreakpoint(project, editor);
- return pair.first != null && pair.second instanceof BreakpointWithHighlighter;
- }
-}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java
index 89e32bc28683..498ee6d44417 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java
@@ -35,6 +35,7 @@ import java.util.List;
public class JumpToObjectAction extends DebuggerAction{
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.JumpToObjectAction");
+ @Override
public void actionPerformed(AnActionEvent e) {
DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext());
if(selectedNode == null) {
@@ -55,6 +56,7 @@ public class JumpToObjectAction extends DebuggerAction{
debugProcess.getManagerThread().schedule(new NavigateCommand(debuggerContext, (ValueDescriptor)descriptor, debugProcess, e));
}
+ @Override
public void update(final AnActionEvent e) {
if(!isFirstStart(e)) {
return;
@@ -82,7 +84,7 @@ public class JumpToObjectAction extends DebuggerAction{
}
}
- private SourcePosition calcPosition(final ValueDescriptor descriptor, final DebugProcessImpl debugProcess) throws ClassNotLoadedException {
+ private static SourcePosition calcPosition(final ValueDescriptor descriptor, final DebugProcessImpl debugProcess) throws ClassNotLoadedException {
final Value value = descriptor.getValue();
if(value == null) {
return null;
@@ -103,10 +105,11 @@ public class JumpToObjectAction extends DebuggerAction{
if(locations.size() > 0) {
final Location location = locations.get(0);
return ApplicationManager.getApplication().runReadAction(new Computable<SourcePosition>() {
+ @Override
public SourcePosition compute() {
SourcePosition position = debugProcess.getPositionManager().getSourcePosition(location);
// adjust position for non-anonymous classes
- if (clsType.name().indexOf("$") < 0) {
+ if (clsType.name().indexOf('$') < 0) {
final PsiClass classAt = position != null? JVMNameUtil.getClassAt(position) : null;
if (classAt != null) {
final SourcePosition classPosition = SourcePosition.createFromElement(classAt);
@@ -130,13 +133,15 @@ public class JumpToObjectAction extends DebuggerAction{
return null;
}
- private class NavigateCommand extends SourcePositionCommand {
+ private static class NavigateCommand extends SourcePositionCommand {
public NavigateCommand(final DebuggerContextImpl debuggerContext, final ValueDescriptor descriptor, final DebugProcessImpl debugProcess, final AnActionEvent e) {
super(debuggerContext, descriptor, debugProcess, e);
}
+ @Override
protected NavigateCommand createRetryCommand() {
return new NavigateCommand(myDebuggerContext, myDescriptor, myDebugProcess, myActionEvent);
}
+ @Override
protected void doAction(final SourcePosition sourcePosition) {
if (sourcePosition != null) {
sourcePosition.navigate(true);
@@ -144,19 +149,21 @@ public class JumpToObjectAction extends DebuggerAction{
}
}
- private class EnableCommand extends SourcePositionCommand {
+ private static class EnableCommand extends SourcePositionCommand {
public EnableCommand(final DebuggerContextImpl debuggerContext, final ValueDescriptor descriptor, final DebugProcessImpl debugProcess, final AnActionEvent e) {
super(debuggerContext, descriptor, debugProcess, e);
}
+ @Override
protected EnableCommand createRetryCommand() {
return new EnableCommand(myDebuggerContext, myDescriptor, myDebugProcess, myActionEvent);
}
+ @Override
protected void doAction(final SourcePosition sourcePosition) {
enableAction(myActionEvent, sourcePosition != null);
}
}
- public abstract class SourcePositionCommand extends SuspendContextCommandImpl {
+ public abstract static class SourcePositionCommand extends SuspendContextCommandImpl {
protected final DebuggerContextImpl myDebuggerContext;
protected final ValueDescriptor myDescriptor;
protected final DebugProcessImpl myDebugProcess;
@@ -173,6 +180,7 @@ public class JumpToObjectAction extends DebuggerAction{
myActionEvent = actionEvent;
}
+ @Override
public final void contextAction() throws Exception {
try {
doAction(calcPosition(myDescriptor, myDebugProcess));
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java
index d67b2bf45572..6eedff4136ea 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java
@@ -21,34 +21,37 @@
package com.intellij.debugger.actions;
import com.intellij.debugger.DebuggerManagerEx;
-import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.debugger.impl.DebuggerSession;
+import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.debugger.ui.ValueHint;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
-import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
import com.intellij.xdebugger.impl.evaluate.quick.common.AbstractValueHint;
+import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
public class QuickEvaluateActionHandler extends QuickEvaluateHandler {
-
+ @Override
public boolean isEnabled(@NotNull final Project project) {
DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(project).getContext().getDebuggerSession();
return debuggerSession != null && debuggerSession.isPaused();
}
+ @Override
public AbstractValueHint createValueHint(@NotNull final Project project, @NotNull final Editor editor, @NotNull final Point point, final ValueHintType type) {
return ValueHint.createValueHint(project, editor, point, type);
}
+ @Override
public boolean canShowHint(@NotNull final Project project) {
DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(project).getContext().getDebuggerSession();
return debuggerSession != null && debuggerSession.isAttached();
}
+ @Override
public int getValueLookupDelay(final Project project) {
return DebuggerSettings.getInstance().VALUE_LOOKUP_DELAY;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java
index fda3e6128a3e..693b7f4917a5 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java
@@ -22,7 +22,6 @@ 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.PlatformDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
@@ -41,7 +40,7 @@ public class ToggleBreakpointEnabledAction extends AnAction {
Breakpoint breakpoint = findBreakpoint(project);
if (breakpoint != null) {
final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager();
- breakpointManager.setBreakpointEnabled(breakpoint, !breakpoint.ENABLED);
+ breakpointManager.setBreakpointEnabled(breakpoint, !breakpoint.isEnabled());
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java
index 39a397755a5e..a7e00ee0dd72 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java
@@ -81,7 +81,7 @@ public class ToggleFieldBreakpointAction extends AnAction {
long id = object.uniqueID();
InstanceFilter[] instanceFilters = new InstanceFilter[] { InstanceFilter.create(Long.toString(id))};
fieldBreakpoint.setInstanceFilters(instanceFilters);
- fieldBreakpoint.INSTANCE_FILTERS_ENABLED = true;
+ fieldBreakpoint.setInstanceFiltersEnabled(true);
}
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleLineBreakpointActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleLineBreakpointActionHandler.java
deleted file mode 100644
index 650e7c37cf70..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleLineBreakpointActionHandler.java
+++ /dev/null
@@ -1,163 +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.codeInsight.folding.impl.actions.ExpandRegionAction;
-import com.intellij.debugger.DebuggerManagerEx;
-import com.intellij.debugger.engine.DebuggerUtils;
-import com.intellij.debugger.engine.requests.RequestManagerImpl;
-import com.intellij.debugger.ui.breakpoints.Breakpoint;
-import com.intellij.debugger.ui.breakpoints.BreakpointManager;
-import com.intellij.debugger.ui.breakpoints.LineBreakpoint;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.FoldRegion;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.fileEditor.FileEditorManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class ToggleLineBreakpointActionHandler extends DebuggerActionHandler {
-
- private final boolean myTemporary;
-
- public ToggleLineBreakpointActionHandler(boolean temporary) {
-
- myTemporary = temporary;
- }
-
- public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) {
- PlaceInDocument place = getPlace(project, event);
- if (place != null) {
- final Document document = place.getDocument();
- final int offset = place.getOffset();
- int line = document.getLineNumber(offset);
-
- VirtualFile file = FileDocumentManager.getInstance().getFile(document);
- PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
- if (DebuggerUtils.supportsJVMDebugging(file.getFileType()) || DebuggerUtils.supportsJVMDebugging(psiFile)) {
- final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager();
- return breakpointManager.findBreakpoint(document, offset, LineBreakpoint.CATEGORY) != null ||
- LineBreakpoint.canAddLineBreakpoint(project, document, line);
- }
- }
-
- return false;
- }
-
- public void perform(@NotNull final Project project, final AnActionEvent event) {
- PlaceInDocument place = getPlace(project, event);
- if(place == null) {
- return;
- }
-
- Editor editor = event.getData(CommonDataKeys.EDITOR);
- ExpandRegionAction.expandRegionAtCaret(project, editor);
-
- Document document = place.getDocument();
- int line = document.getLineNumber(place.getOffset());
- if (editor != null && editor.getCaretModel().getVisualPosition().line != line) {
- editor.getCaretModel().moveToOffset(place.getOffset());
- }
-
- DebuggerManagerEx debugManager = DebuggerManagerEx.getInstanceEx(project);
- if (debugManager == null) {
- return;
- }
- BreakpointManager manager = debugManager.getBreakpointManager();
- final Breakpoint breakpoint = manager.findBreakpoint(document, place.getOffset(), LineBreakpoint.CATEGORY);
- if(breakpoint == null) {
- LineBreakpoint lineBreakpoint = manager.addLineBreakpoint(document, line);
- if(lineBreakpoint != null) {
- lineBreakpoint.REMOVE_AFTER_HIT = myTemporary;
- RequestManagerImpl.createRequests(lineBreakpoint);
- }
- }
- else {
- if (!breakpoint.REMOVE_AFTER_HIT && myTemporary) {
- breakpoint.REMOVE_AFTER_HIT = true;
- breakpoint.updateUI();
- }
- else {
- manager.removeBreakpoint(breakpoint);
- }
- }
- }
-
- private static boolean containsOnlyDeclarations(int line, Document document, PsiFile file) {
- int lineStart = document.getLineStartOffset(line);
- int lineEnd = document.getLineEndOffset(line);
- PsiElement start = file.findElementAt(lineStart);
- PsiElement end = file.findElementAt(lineEnd - 1);
- if (start == null || end == null) return false;
-
- PsiElement commonParent = PsiTreeUtil.findCommonParent(start, end);
- for (PsiElement element : PsiTreeUtil.findChildrenOfAnyType(commonParent, PsiStatement.class, PsiExpression.class)) {
- if (new TextRange(lineStart, lineEnd).contains(element.getTextRange().getStartOffset())) {
- return false;
- }
- }
- return true;
- }
-
- @Nullable
- private static PlaceInDocument getPlace(@NotNull final Project project, AnActionEvent event) {
- Editor editor = event.getData(CommonDataKeys.EDITOR);
- if(editor == null) {
- editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
- }
- if (editor == null) {
- return null;
- }
-
- final Document document = editor.getDocument();
- PsiDocumentManager.getInstance(project).commitDocument(document);
- PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
- if (file == null) {
- return null;
- }
-
- // if several lines are merged into one visual line (using folding), try to find the most appropriate of those lines
- int visualLine = editor.getCaretModel().getVisualPosition().getLine();
- int visibleOffset = editor.getCaretModel().getOffset();
- while (editor.offsetToVisualPosition(visibleOffset).line == visualLine) {
- int line = document.getLineNumber(visibleOffset);
- if (!containsOnlyDeclarations(line, document, file)) {
- return new PlaceInDocument(document, visibleOffset);
- }
- int lineEndOffset = document.getLineEndOffset(line);
- FoldRegion region = editor.getFoldingModel().getCollapsedRegionAtOffset(lineEndOffset);
- if (region != null) {
- int foldEnd = region.getEndOffset();
- if (foldEnd > lineEndOffset) {
- visibleOffset = foldEnd;
- continue;
- }
- }
- visibleOffset = lineEndOffset + 1;
- }
-
- return new PlaceInDocument(document, editor.getCaretModel().getOffset());
- }
-} \ No newline at end of file
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 49d3cae977f0..399c55fd00e5 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java
@@ -17,22 +17,24 @@ package com.intellij.debugger.engine;
import com.intellij.debugger.NoDataException;
import com.intellij.debugger.PositionManager;
+import com.intellij.debugger.PositionManagerEx;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.requests.ClassPrepareRequestor;
-import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.xdebugger.frame.XStackFrame;
import com.sun.jdi.Location;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.request.ClassPrepareRequest;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-public class CompoundPositionManager implements PositionManager{
- private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.CompoundPositionManager");
+public class CompoundPositionManager extends PositionManagerEx {
private final ArrayList<PositionManager> myPositionManagers = new ArrayList<PositionManager>();
+ @SuppressWarnings("UnusedDeclaration")
public CompoundPositionManager() {
}
@@ -45,6 +47,7 @@ public class CompoundPositionManager implements PositionManager{
myPositionManagers.add(0, manager);
}
+ @Override
public SourcePosition getSourcePosition(Location location) {
for (PositionManager positionManager : myPositionManagers) {
try {
@@ -56,6 +59,7 @@ public class CompoundPositionManager implements PositionManager{
return null;
}
+ @Override
@NotNull
public List<ReferenceType> getAllClasses(SourcePosition classPosition) {
for (PositionManager positionManager : myPositionManagers) {
@@ -68,6 +72,7 @@ public class CompoundPositionManager implements PositionManager{
return Collections.emptyList();
}
+ @Override
@NotNull
public List<Location> locationsOfLine(ReferenceType type, SourcePosition position) {
for (PositionManager positionManager : myPositionManagers) {
@@ -80,6 +85,7 @@ public class CompoundPositionManager implements PositionManager{
return Collections.emptyList();
}
+ @Override
public ClassPrepareRequest createPrepareRequest(ClassPrepareRequestor requestor, SourcePosition position) {
for (PositionManager positionManager : myPositionManagers) {
try {
@@ -91,4 +97,18 @@ public class CompoundPositionManager implements PositionManager{
return null;
}
+
+ @Nullable
+ @Override
+ public XStackFrame createStackFrame(@NotNull Location location) {
+ for (PositionManager positionManager : myPositionManagers) {
+ if (positionManager instanceof PositionManagerEx) {
+ XStackFrame xStackFrame = ((PositionManagerEx)positionManager).createStackFrame(location);
+ if (xStackFrame != null) {
+ return xStackFrame;
+ }
+ }
+ }
+ return null;
+ }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java b/java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java
index bfd7d050adc8..26903c87ca4f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java
@@ -53,8 +53,8 @@ public class ContextUtil {
try {
location = frameProxy.location();
}
- catch (Throwable th) {
- LOG.debug(th);
+ catch (Throwable e) {
+ LOG.debug(e);
}
final CompoundPositionManager positionManager = debugProcess.getPositionManager();
if (positionManager == null) {
@@ -63,7 +63,8 @@ public class ContextUtil {
}
try {
return positionManager.getSourcePosition(location);
- } catch (IndexNotReadyException e) {
+ }
+ catch (IndexNotReadyException ignored) {
return null;
}
}
@@ -124,10 +125,10 @@ public class ContextUtil {
}
return codeBlockFromText;
}
- catch (IncorrectOperationException e) {
+ catch (IncorrectOperationException ignored) {
return element;
}
- catch (EvaluateException e) {
+ catch (EvaluateException ignored) {
return element;
}
finally {
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 a5b1be2ba733..b660d5f1ed6e 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
@@ -57,9 +57,9 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.PsiDocumentManager;
@@ -77,6 +77,7 @@ import com.sun.jdi.connect.*;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.EventRequestManager;
import com.sun.jdi.request.StepRequest;
+import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -88,7 +89,7 @@ import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
-public abstract class DebugProcessImpl implements DebugProcess {
+public abstract class DebugProcessImpl extends UserDataHolderBase implements DebugProcess {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.DebugProcessImpl");
@NonNls private static final String SOCKET_ATTACHING_CONNECTOR_NAME = "com.sun.jdi.SocketAttach";
@@ -111,26 +112,26 @@ public abstract class DebugProcessImpl implements DebugProcess {
protected static final int STATE_DETACHED = 3;
protected final AtomicInteger myState = new AtomicInteger(STATE_INITIAL);
- private ExecutionResult myExecutionResult;
+ private ExecutionResult myExecutionResult;
private RemoteConnection myConnection;
private ConnectionServiceWrapper myConnectionService;
private Map<String, Connector.Argument> myArguments;
private final List<NodeRenderer> myRenderers = new ArrayList<NodeRenderer>();
- private final Map<Type, NodeRenderer> myNodeRederersMap = new com.intellij.util.containers.HashMap<Type, NodeRenderer>();
- private final NodeRendererSettingsListener mySettingsListener = new NodeRendererSettingsListener() {
- public void renderersChanged() {
- myNodeRederersMap.clear();
- myRenderers.clear();
- loadRenderers();
- }
- };
+ private final Map<Type, NodeRenderer> myNodeRenderersMap = new THashMap<Type, NodeRenderer>();
+ private final NodeRendererSettingsListener mySettingsListener = new NodeRendererSettingsListener() {
+ @Override
+ public void renderersChanged() {
+ myNodeRenderersMap.clear();
+ myRenderers.clear();
+ loadRenderers();
+ }
+ };
private final SuspendManagerImpl mySuspendManager = new SuspendManagerImpl(this);
protected CompoundPositionManager myPositionManager = null;
private volatile DebuggerManagerThreadImpl myDebuggerManagerThread;
- private final HashMap myUserData = new HashMap();
private static final int LOCAL_START_TIMEOUT = 30000;
private final Semaphore myWaitFor = new Semaphore();
@@ -141,9 +142,6 @@ public abstract class DebugProcessImpl implements DebugProcess {
private final Disposable myDisposable = Disposer.newDisposable();
private final Alarm myStatusUpdateAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, myDisposable);
- /** @noinspection FieldCanBeLocal*/
- private volatile boolean myDebugProcessStarted = false;
-
protected DebugProcessImpl(Project project) {
myProject = project;
myRequestManager = new RequestManagerImpl(this);
@@ -153,6 +151,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
private void loadRenderers() {
getManagerThread().invoke(new DebuggerCommandImpl() {
+ @Override
protected void action() throws Exception {
try {
final NodeRendererSettings rendererSettings = NodeRendererSettings.getInstance();
@@ -164,6 +163,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
}
finally {
DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() {
+ @Override
public void run() {
final DebuggerSession session = mySession;
if (session != null && session.isAttached()) {
@@ -215,7 +215,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
return getDefaultRenderer(type);
}
- NodeRenderer renderer = myNodeRederersMap.get(type);
+ NodeRenderer renderer = myNodeRenderersMap.get(type);
if(renderer == null) {
for (final NodeRenderer nodeRenderer : myRenderers) {
if (nodeRenderer.isApplicable(type)) {
@@ -226,7 +226,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
if (renderer == null) {
renderer = getDefaultRenderer(type);
}
- myNodeRederersMap.put(type, renderer);
+ myNodeRenderersMap.put(type, renderer);
}
return renderer;
@@ -308,7 +308,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
private void stopConnecting() {
DebuggerManagerThreadImpl.assertIsManagerThread();
- Map arguments = myArguments;
+ Map<String, Connector.Argument> arguments = myArguments;
try {
if (arguments == null) {
return;
@@ -423,7 +423,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
final List<StepRequest> toDelete = new ArrayList<StepRequest>(stepRequests.size());
for (final StepRequest request : stepRequests) {
ThreadReference threadReference = request.thread();
- // [jeka] on attempt to delete a request assigned to a thread with unknown status, a JDWP error occures
+ // [jeka] on attempt to delete a request assigned to a thread with unknown status, a JDWP error occurs
try {
if (threadReference.status() != ThreadReference.THREAD_STATUS_UNKNOWN && (stepThread == null || stepThread.equals(threadReference))) {
toDelete.add(request);
@@ -444,7 +444,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
StackFrameProxyImpl stackFrame = thread.frame(0);
if (stackFrame != null) {
Location location = stackFrame.location();
- ReferenceType referenceType = location.declaringType();
+ ReferenceType referenceType = location == null ? null : location.declaringType();
if (referenceType != null) {
return referenceType.name();
}
@@ -477,7 +477,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
if (address == null) {
throw new CantRunException(DebuggerBundle.message("error.no.debug.listen.port"));
}
- // negative port number means the caller leaves to debugger to decide at which hport to listen
+ // negative port number means the caller leaves to debugger to decide at which port to listen
//noinspection HardCodedStringLiteral
final Connector.Argument portArg = myConnection.isUseSockets() ? myArguments.get("port") : myArguments.get("name");
if (portArg != null) {
@@ -498,10 +498,10 @@ public abstract class DebugProcessImpl implements DebugProcess {
try {
connector.stopListening(myArguments);
}
- catch (IllegalArgumentException e) {
+ catch (IllegalArgumentException ignored) {
// ignored
}
- catch (IllegalConnectorArgumentsException e) {
+ catch (IllegalConnectorArgumentsException ignored) {
// ignored
}
}
@@ -572,6 +572,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
if (!myStatusUpdateAlarm.isDisposed()) {
myStatusUpdateAlarm.cancelAllRequests();
myStatusUpdateAlarm.addRequest(new Runnable() {
+ @Override
public void run() {
final WindowManager wm = WindowManager.getInstance();
if (wm != null) {
@@ -614,6 +615,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
final String version = vm.version();
if ("1.4.0".equals(version)) {
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
Messages.showMessageDialog(
getProject(),
@@ -633,10 +635,12 @@ public abstract class DebugProcessImpl implements DebugProcess {
myEvaluationDispatcher.removeListener(evaluationListener);
}
+ @Override
public void addDebugProcessListener(DebugProcessListener listener) {
myDebugProcessDispatcher.addListener(listener);
}
+ @Override
public void removeDebugProcessListener(DebugProcessListener listener) {
myDebugProcessDispatcher.removeListener(listener);
}
@@ -668,18 +672,12 @@ public abstract class DebugProcessImpl implements DebugProcess {
return myConnection;
}
+ @Override
public ExecutionResult getExecutionResult() {
return myExecutionResult;
}
- public <T> T getUserData(Key<T> key) {
- return (T)myUserData.get(key);
- }
-
- public <T> void putUserData(Key<T> key, T value) {
- myUserData.put(key, value);
- }
-
+ @Override
public Project getProject() {
return myProject;
}
@@ -698,22 +696,27 @@ public abstract class DebugProcessImpl implements DebugProcess {
return myState.get() == STATE_INITIAL;
}
+ @Override
public boolean isAttached() {
return myState.get() == STATE_ATTACHED;
}
+ @Override
public boolean isDetached() {
return myState.get() == STATE_DETACHED;
}
+ @Override
public boolean isDetaching() {
return myState.get() == STATE_DETACHING;
}
+ @Override
public RequestManagerImpl getRequestsManager() {
return myRequestManager;
}
+ @Override
public VirtualMachineProxyImpl getVirtualMachineProxy() {
DebuggerManagerThreadImpl.assertIsManagerThread();
final VirtualMachineProxyImpl vm = myVirtualMachineProxy;
@@ -723,6 +726,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
return vm;
}
+ @Override
public void appendPositionManager(final PositionManager positionManager) {
DebuggerManagerThreadImpl.assertIsManagerThread();
myPositionManager.appendPositionManager(positionManager);
@@ -756,7 +760,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
myVirtualMachineProxy = null;
myPositionManager = null;
myReturnValueWatcher = null;
- myNodeRederersMap.clear();
+ myNodeRenderersMap.clear();
myRenderers.clear();
DebuggerUtils.cleanupAfterProcessFinish(this);
myState.set(STATE_DETACHED);
@@ -852,6 +856,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
Disposer.dispose(myDisposable);
}
+ @Override
public DebuggerManagerThreadImpl getManagerThread() {
if (myDebuggerManagerThread == null) {
synchronized (this) {
@@ -868,11 +873,13 @@ public abstract class DebugProcessImpl implements DebugProcess {
return suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD ? ObjectReference.INVOKE_SINGLE_THREADED : 0;
}
+ @Override
public void waitFor() {
LOG.assertTrue(!DebuggerManagerThreadImpl.isManagerThread());
myWaitFor.waitFor();
}
+ @Override
public void waitFor(long timeout) {
LOG.assertTrue(!DebuggerManagerThreadImpl.isManagerThread());
myWaitFor.waitFor(timeout);
@@ -1002,6 +1009,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
final Exception[] exception = new Exception[1];
final Value[] result = new Value[1];
getManagerThread().startLongProcessAndFork(new Runnable() {
+ @Override
public void run() {
ThreadReferenceProxyImpl thread = context.getThread();
try {
@@ -1075,14 +1083,17 @@ public abstract class DebugProcessImpl implements DebugProcess {
}
}
+ @Override
public Value invokeMethod(final EvaluationContext evaluationContext, final ObjectReference objRef, final Method method, final List args) throws EvaluateException {
return invokeInstanceMethod(evaluationContext, objRef, method, args, 0);
}
+ @Override
public Value invokeInstanceMethod(final EvaluationContext evaluationContext, final ObjectReference objRef, final Method method,
final List args, final int invocationOptions) throws EvaluateException {
final ThreadReference thread = getEvaluationThread(evaluationContext);
return new InvokeCommand<Value>(args) {
+ @Override
protected Value invokeMethod(int invokePolicy, final List args) throws InvocationException, ClassNotLoadedException, IncompatibleThreadStateException, InvalidTypeException {
if (LOG.isDebugEnabled()) {
LOG.debug("Invoke " + method.name());
@@ -1100,12 +1111,14 @@ public abstract class DebugProcessImpl implements DebugProcess {
return evaluationThread.getThreadReference();
}
+ @Override
public Value invokeMethod(final EvaluationContext evaluationContext, final ClassType classType,
final Method method,
final List args) throws EvaluateException {
final ThreadReference thread = getEvaluationThread(evaluationContext);
InvokeCommand<Value> invokeCommand = new InvokeCommand<Value>(args) {
+ @Override
protected Value invokeMethod(int invokePolicy, final List args) throws InvocationException,
ClassNotLoadedException,
IncompatibleThreadStateException,
@@ -1119,17 +1132,20 @@ public abstract class DebugProcessImpl implements DebugProcess {
return invokeCommand.start((EvaluationContextImpl)evaluationContext, method);
}
+ @Override
public ArrayReference newInstance(final ArrayType arrayType,
final int dimension)
throws EvaluateException {
return arrayType.newInstance(dimension);
}
+ @Override
public ObjectReference newInstance(final EvaluationContext evaluationContext, final ClassType classType,
final Method method,
final List args) throws EvaluateException {
final ThreadReference thread = getEvaluationThread(evaluationContext);
InvokeCommand<ObjectReference> invokeCommand = new InvokeCommand<ObjectReference>(args) {
+ @Override
protected ObjectReference invokeMethod(int invokePolicy, final List args) throws InvocationException,
ClassNotLoadedException,
IncompatibleThreadStateException,
@@ -1181,6 +1197,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
showStatusText("");
}
+ @Override
public ReferenceType findClass(EvaluationContext evaluationContext, String className,
ClassLoaderReference classLoader) throws EvaluateException {
try {
@@ -1255,7 +1272,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
}
}
- @SuppressWarnings({"HardCodedStringLiteral"})
+ @SuppressWarnings({"HardCodedStringLiteral", "SpellCheckingInspection"})
public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String qName, ClassLoaderReference classLoader)
throws InvocationException, ClassNotLoadedException, IncompatibleThreadStateException, InvalidTypeException, EvaluateException {
@@ -1308,13 +1325,15 @@ public abstract class DebugProcessImpl implements DebugProcess {
return mySuspendManager;
}
+ @Override
public CompoundPositionManager getPositionManager() {
return myPositionManager;
}
//ManagerCommands
+ @Override
public void stop(boolean forceTerminate) {
- this.getManagerThread().terminateAndInvoke(createStopCommand(forceTerminate), DebuggerManagerThreadImpl.COMMAND_TIMEOUT);
+ getManagerThread().terminateAndInvoke(createStopCommand(forceTerminate), DebuggerManagerThreadImpl.COMMAND_TIMEOUT);
}
public StopCommand createStopCommand(boolean forceTerminate) {
@@ -1328,10 +1347,12 @@ public abstract class DebugProcessImpl implements DebugProcess {
myIsTerminateTargetVM = isTerminateTargetVM;
}
+ @Override
public Priority getPriority() {
return Priority.HIGH;
}
+ @Override
protected void action() throws Exception {
if (isAttached()) {
final VirtualMachineProxyImpl virtualMachineProxy = getVirtualMachineProxy();
@@ -1339,8 +1360,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
virtualMachineProxy.exit(-1);
}
else {
- // some VM's (like IBM VM 1.4.2 bundled with WebSpere) does not
- // resume threads on dispose() like it should
+ // some VMs (like IBM VM 1.4.2 bundled with WebSphere) does not resume threads on dispose() like it should
try {
virtualMachineProxy.resume();
}
@@ -1360,6 +1380,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
super(suspendContext);
}
+ @Override
public void contextAction() {
showStatusText(DebuggerBundle.message("status.step.out"));
final SuspendContextImpl suspendContext = getSuspendContext();
@@ -1391,6 +1412,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
null;
}
+ @Override
public void contextAction() {
showStatusText(DebuggerBundle.message("status.step.into"));
final SuspendContextImpl suspendContext = getSuspendContext();
@@ -1409,7 +1431,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
hint.setIgnoreFilters(myForcedIgnoreFilters || mySession.shouldIgnoreSteppingFilters());
applyThreadFilter(stepThread);
if (myBreakpoint != null) {
- myBreakpoint.SUSPEND_POLICY = suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL;
+ myBreakpoint.setSuspendPolicy(suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL);
myBreakpoint.createRequest(suspendContext.getDebugProcess());
myRunToCursorBreakpoint = myBreakpoint;
}
@@ -1426,11 +1448,12 @@ public abstract class DebugProcessImpl implements DebugProcess {
myIsIgnoreBreakpoints = ignoreBreakpoints;
}
+ @Override
public void contextAction() {
showStatusText(DebuggerBundle.message("status.step.over"));
final SuspendContextImpl suspendContext = getSuspendContext();
final ThreadReferenceProxyImpl stepThread = getContextThread();
- // need this hint whil stepping over for JSR45 support:
+ // need this hint while stepping over for JSR45 support:
// several lines of generated java code may correspond to a single line in the source file,
// from which the java code was generated
RequestHint hint = new RequestHint(stepThread, suspendContext, StepRequest.STEP_OVER);
@@ -1464,6 +1487,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
myRunToCursorBreakpoint = breakpointManager.addRunToCursorBreakpoint(document, lineIndex, ignoreBreakpoints);
}
+ @Override
public void contextAction() {
showStatusText(DebuggerBundle.message("status.run.to.cursor"));
cancelRunToCursorBreakpoint();
@@ -1476,8 +1500,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
}
applyThreadFilter(getContextThread());
final SuspendContextImpl context = getSuspendContext();
- myRunToCursorBreakpoint.SUSPEND_POLICY = context.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL;
- myRunToCursorBreakpoint.LOG_ENABLED = false;
+ myRunToCursorBreakpoint.setSuspendPolicy(context.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL);
myRunToCursorBreakpoint.createRequest(context.getDebugProcess());
DebugProcessImpl.this.myRunToCursorBreakpoint = myRunToCursorBreakpoint;
super.contextAction();
@@ -1494,10 +1517,12 @@ public abstract class DebugProcessImpl implements DebugProcess {
myContextThread = contextThread != null ? contextThread : (suspendContext != null? suspendContext.getThread() : null);
}
+ @Override
public Priority getPriority() {
return Priority.HIGH;
}
+ @Override
public void contextAction() {
showStatusText(DebuggerBundle.message("status.process.resumed"));
getSuspendManager().resume(getSuspendContext());
@@ -1524,6 +1549,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
public PauseCommand() {
}
+ @Override
public void action() {
if (!isAttached() || getVirtualMachineProxy().isPausePressed()) {
return;
@@ -1544,6 +1570,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
myThread = thread;
}
+ @Override
public void contextAction() {
if (getSuspendManager().isFrozen(myThread)) {
getSuspendManager().unfreezeThread(myThread);
@@ -1553,7 +1580,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
final Set<SuspendContextImpl> suspendingContexts = SuspendManagerUtil.getSuspendingContexts(getSuspendManager(), myThread);
for (SuspendContextImpl suspendContext : suspendingContexts) {
if (suspendContext.getThread() == myThread) {
- DebugProcessImpl.this.getManagerThread().invoke(createResumeCommand(suspendContext));
+ getManagerThread().invoke(createResumeCommand(suspendContext));
}
else {
getSuspendManager().resumeThread(suspendContext, myThread);
@@ -1569,6 +1596,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
myThread = thread;
}
+ @Override
protected void action() throws Exception {
SuspendManager suspendManager = getSuspendManager();
if (!suspendManager.isFrozen(myThread)) {
@@ -1585,6 +1613,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
myStackFrame = frameProxy;
}
+ @Override
public void contextAction() {
final ThreadReferenceProxyImpl thread = myStackFrame.threadProxy();
try {
@@ -1593,7 +1622,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
return;
}
}
- catch (ObjectCollectedException e) {
+ catch (ObjectCollectedException ignored) {
notifyCancelled();
return;
}
@@ -1606,6 +1635,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
if (myStackFrame.isBottom()) {
DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() {
+ @Override
public void run() {
Messages.showMessageDialog(myProject, DebuggerBundle.message("error.pop.bottom.stackframe"), ActionsBundle.actionText(DebuggerActions.POP_FRAME), Messages.getErrorIcon());
}
@@ -1618,6 +1648,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
}
catch (final EvaluateException e) {
DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() {
+ @Override
public void run() {
Messages.showMessageDialog(myProject, DebuggerBundle.message("error.pop.stackframe", e.getLocalizedMessage()), ActionsBundle.actionText(DebuggerActions.POP_FRAME), Messages.getErrorIcon());
}
@@ -1630,6 +1661,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
}
}
+ @Override
@NotNull
public GlobalSearchScope getSearchScope() {
LOG.assertTrue(mySession != null, "Accessing debug session before its initialization");
@@ -1668,7 +1700,6 @@ public abstract class DebugProcessImpl implements DebugProcess {
}
// writing to volatile field ensures the other threads will see the right values in non-volatile fields
- myDebugProcessStarted = true;
if (ApplicationManager.getApplication().isUnitTestMode()) {
return myExecutionResult;
@@ -1719,6 +1750,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
final Ref<Boolean> connectorIsReady = Ref.create(false);
myDebugProcessDispatcher.addListener(new DebugProcessAdapter() {
+ @Override
public void connectorIsReady() {
connectorIsReady.set(true);
semaphore.up();
@@ -1727,7 +1759,8 @@ public abstract class DebugProcessImpl implements DebugProcess {
});
- this.getManagerThread().schedule(new DebuggerCommandImpl() {
+ getManagerThread().schedule(new DebuggerCommandImpl() {
+ @Override
protected void action() {
VirtualMachine vm = null;
@@ -1744,7 +1777,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
try {
wait(500);
}
- catch (InterruptedException ie) {
+ catch (InterruptedException ignored) {
break;
}
}
@@ -1752,10 +1785,11 @@ public abstract class DebugProcessImpl implements DebugProcess {
else {
fail();
if (myExecutionResult != null || !connectorIsReady.get()) {
- // propagate exception only in case we succeded to obtain execution result,
+ // propagate exception only in case we succeeded to obtain execution result,
// otherwise if the error is induced by the fact that there is nothing to debug, and there is no need to show
// this problem to the user
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
ExecutionUtil.handleExecutionError(myProject, ToolWindowId.DEBUG, sessionName, e);
}
@@ -1773,8 +1807,10 @@ public abstract class DebugProcessImpl implements DebugProcess {
if (vm != null) {
final VirtualMachine vm1 = vm;
afterProcessStarted(new Runnable() {
+ @Override
public void run() {
getManagerThread().schedule(new DebuggerCommandImpl() {
+ @Override
protected void action() throws Exception {
commitVM(vm1);
}
@@ -1784,6 +1820,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
}
}
+ @Override
protected void commandCancelled() {
try {
super.commandCancelled();
@@ -1809,6 +1846,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
removeProcessListener(this);
}
+ @Override
public void startNotified(ProcessEvent event) {
run();
}
@@ -1838,11 +1876,13 @@ public abstract class DebugProcessImpl implements DebugProcess {
public ResumeCommand createResumeCommand(SuspendContextImpl suspendContext, final PrioritizedTask.Priority priority) {
final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager();
return new ResumeCommand(suspendContext) {
+ @Override
public void contextAction() {
breakpointManager.applyThreadFilter(DebugProcessImpl.this, null); // clear the filter on resume
super.contextAction();
}
+ @Override
public Priority getPriority() {
return priority;
}
@@ -1889,6 +1929,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
public void setBreakpointsMuted(final boolean muted) {
if (isAttached()) {
getManagerThread().schedule(new DebuggerCommandImpl() {
+ @Override
protected void action() throws Exception {
// set the flag before enabling/disabling cause it affects if breakpoints will create requests
if (myBreakpointsMuted.getAndSet(muted) != muted) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/requests/LocatableEventRequestor.java b/java/debugger/impl/src/com/intellij/debugger/engine/requests/LocatableEventRequestor.java
index db64d1d1b553..ed1d7af2e16f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/requests/LocatableEventRequestor.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/requests/LocatableEventRequestor.java
@@ -19,16 +19,9 @@ import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.requests.Requestor;
import com.sun.jdi.event.LocatableEvent;
-/**
- * Created by IntelliJ IDEA.
- * User: lex
- * Date: Jun 27, 2003
- * Time: 8:05:52 PM
- * To change this template use Options | File Templates.
- */
public interface LocatableEventRequestor extends Requestor {
/**
- * @returns true if requesto was hit by the event, false otherwise
+ * @returns true if request was hit by the event, false otherwise
*/
boolean processLocatableEvent(SuspendContextCommandImpl action, LocatableEvent event) throws EventProcessingException;
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 832958759964..c35c971c5a76 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
@@ -30,9 +30,7 @@ import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.debugger.ui.breakpoints.Breakpoint;
import com.intellij.debugger.ui.breakpoints.BreakpointManager;
import com.intellij.debugger.ui.breakpoints.FilteredRequestor;
-import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
@@ -40,15 +38,10 @@ import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiClass;
import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.util.containers.HashMap;
-import com.intellij.xdebugger.XDebuggerManager;
-import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
-import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
import com.sun.jdi.*;
import com.sun.jdi.event.ClassPrepareEvent;
import com.sun.jdi.request.*;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.java.debugger.breakpoints.JavaBreakpointAdapter;
-import org.jetbrains.java.debugger.breakpoints.JavaBreakpointType;
import java.util.Collections;
import java.util.HashSet;
@@ -158,11 +151,11 @@ public class RequestManagerImpl extends DebugProcessAdapterImpl implements Reque
request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
}
- if (requestor.COUNT_FILTER_ENABLED && requestor.COUNT_FILTER > 0) {
- request.addCountFilter(requestor.COUNT_FILTER);
+ if (requestor.isCountFilterEnabled() && requestor.getCountFilter() > 0) {
+ request.addCountFilter(requestor.getCountFilter());
}
- if (requestor.CLASS_FILTERS_ENABLED && !(request instanceof BreakpointRequest) /*no built-in class filters support for breakpoint requests*/ ) {
+ if (requestor.isClassFiltersEnabled() && !(request instanceof BreakpointRequest) /*no built-in class filters support for breakpoint requests*/ ) {
ClassFilter[] classFilters = requestor.getClassFilters();
if (DebuggerUtilsEx.getEnabledNumber(classFilters) == 1) {
for (final ClassFilter filter : classFilters) {
@@ -408,17 +401,18 @@ public class RequestManagerImpl extends DebugProcessAdapterImpl implements Reque
breakpoint.createRequest(myDebugProcess);
}
- AccessToken token = ReadAction.start();
- try {
- JavaBreakpointAdapter adapter = new JavaBreakpointAdapter(project);
- for (XLineBreakpoint<XBreakpointProperties> breakpoint : XDebuggerManager.getInstance(project).getBreakpointManager()
- .getBreakpoints(JavaBreakpointType.class)) {
- adapter.getOrCreate(breakpoint).createRequest(myDebugProcess);
- }
- }
- finally {
- token.finish();
- }
+ //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();
+ //}
}
});
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextImpl.java
index e35ba834a9b5..640f76cad628 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextImpl.java
@@ -42,7 +42,7 @@ import org.jetbrains.annotations.Nullable;
public final class DebuggerContextImpl implements DebuggerContext {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerContextImpl");
- public static final DebuggerContextImpl EMPTY_CONTEXT = DebuggerContextImpl.createDebuggerContext((DebuggerSession) null, null, null, null);
+ public static final DebuggerContextImpl EMPTY_CONTEXT = createDebuggerContext((DebuggerSession)null, null, null, null);
private boolean myInitialized;
@@ -58,7 +58,7 @@ public final class DebuggerContextImpl implements DebuggerContext {
private DebuggerContextImpl(@Nullable DebuggerSession session, DebugProcessImpl debugProcess, SuspendContextImpl context, ThreadReferenceProxyImpl threadProxy, StackFrameProxyImpl frameProxy, SourcePosition position, PsiElement contextElement, boolean initialized) {
LOG.assertTrue(frameProxy == null || threadProxy == null || threadProxy == frameProxy.threadProxy());
- LOG.assertTrue(debugProcess == null ? frameProxy == null && threadProxy == null : true);
+ LOG.assertTrue(debugProcess != null || frameProxy == null && threadProxy == null);
myDebuggerSession = session;
myThreadProxy = threadProxy;
myFrameProxy = frameProxy;
@@ -74,6 +74,7 @@ public final class DebuggerContextImpl implements DebuggerContext {
return myDebuggerSession;
}
+ @Override
public DebugProcessImpl getDebugProcess() {
return myDebugProcess;
}
@@ -82,14 +83,17 @@ public final class DebuggerContextImpl implements DebuggerContext {
return myThreadProxy;
}
+ @Override
public SuspendContextImpl getSuspendContext() {
return mySuspendContext;
}
+ @Override
public Project getProject() {
return myDebugProcess != null ? myDebugProcess.getProject() : null;
}
+ @Override
@Nullable
public StackFrameProxyImpl getFrameProxy() {
LOG.assertTrue(myInitialized);
@@ -144,13 +148,14 @@ public final class DebuggerContextImpl implements DebuggerContext {
try {
myFrameProxy = myThreadProxy.frameCount() > 0 ? myThreadProxy.frame(0) : null;
}
- catch (EvaluateException e) {
+ catch (EvaluateException ignored) {
}
}
}
if(myFrameProxy != null) {
PsiDocumentManager.getInstance(getProject()).commitAndRunReadAction(new Runnable() {
+ @Override
public void run() {
if (mySourcePosition == null) {
mySourcePosition = ContextUtil.getSourcePosition(DebuggerContextImpl.this);
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java
index 917dba29b5a8..7837eab31aa8 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java
@@ -16,7 +16,6 @@
package com.intellij.debugger.impl;
import com.intellij.debugger.*;
-import com.intellij.debugger.actions.DebuggerActions;
import com.intellij.debugger.engine.*;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationListener;
@@ -56,6 +55,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.unscramble.ThreadState;
import com.intellij.util.Alarm;
import com.intellij.xdebugger.AbstractDebuggerSession;
+import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.evaluate.quick.common.ValueLookupManager;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.ThreadReference;
@@ -115,6 +115,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
@NotNull
public GlobalSearchScope getSearchScope() {
+ //noinspection ConstantConditions
LOG.assertTrue(mySearchScope != null, "Accessing Session's search scope before its initialization");
return mySearchScope;
}
@@ -134,6 +135,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
myDebuggerContext = SESSION_EMPTY_CONTEXT;
}
+ @Override
public DebuggerContextImpl getContext() {
return myDebuggerContext;
}
@@ -146,11 +148,13 @@ public class DebuggerSession implements AbstractDebuggerSession {
* in this case we assume that the latter setState is ignored
* since the thread was resumed
*/
+ @Override
public void setState(final DebuggerContextImpl context, final int state, final int event, final String description) {
ApplicationManager.getApplication().assertIsDispatchThread();
final DebuggerSession session = context.getDebuggerSession();
LOG.assertTrue(session == DebuggerSession.this || session == null);
final Runnable setStateRunnable = new Runnable() {
+ @Override
public void run() {
LOG.assertTrue(myDebuggerContext.isInitialised());
myDebuggerContext = context;
@@ -170,6 +174,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
}
else {
getProcess().getManagerThread().schedule(new SuspendContextCommandImpl(context.getSuspendContext()) {
+ @Override
public void contextAction() throws Exception {
context.initCaches();
DebuggerInvocationUtil.swingInvokeLater(getProject(), setStateRunnable);
@@ -279,7 +284,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
resumeAction(runToCursorCommand, EVENT_STEP);
}
catch (EvaluateException e) {
- Messages.showErrorDialog(e.getMessage(), ActionsBundle.actionText(DebuggerActions.RUN_TO_CURSOR));
+ Messages.showErrorDialog(e.getMessage(), ActionsBundle.actionText(XDebuggerActions.RUN_TO_CURSOR));
}
}
@@ -335,6 +340,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
}
// ManagerCommands
+ @Override
public boolean isStopped() {
return getState() == STATE_STOPPED;
}
@@ -343,6 +349,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
return !isStopped() && getState() != STATE_WAITING_ATTACH;
}
+ @Override
public boolean isPaused() {
return getState() == STATE_PAUSED;
}
@@ -399,18 +406,21 @@ public class DebuggerSession implements AbstractDebuggerSession {
}
//executed in manager thread
+ @Override
public void connectorIsReady() {
DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
+ @Override
public void run() {
RemoteConnection connection = myDebugProcess.getConnection();
final String addressDisplayName = DebuggerBundle.getAddressDisplayName(connection);
final String transportName = DebuggerBundle.getTransportName(connection);
final String connectionStatusMessage = connection.isServerMode() ? DebuggerBundle.message("status.listening", addressDisplayName, transportName) : DebuggerBundle.message("status.connecting", addressDisplayName, transportName);
- getContextManager().setState(SESSION_EMPTY_CONTEXT, DebuggerSession.STATE_WAITING_ATTACH, DebuggerSession.EVENT_START_WAIT_ATTACH, connectionStatusMessage);
+ getContextManager().setState(SESSION_EMPTY_CONTEXT, STATE_WAITING_ATTACH, EVENT_START_WAIT_ATTACH, connectionStatusMessage);
}
});
}
+ @Override
public void paused(final SuspendContextImpl suspendContext) {
if (LOG.isDebugEnabled()) {
LOG.debug("paused");
@@ -418,6 +428,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
if (!shouldSetAsActiveContext(suspendContext)) {
DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
+ @Override
public void run() {
getContextManager().fireStateChanged(getContextManager().getContext(), EVENT_THREADS_REFRESH);
}
@@ -470,7 +481,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
}
proxy = (currentThread.frameCount() > 0) ? currentThread.frame(0) : null;
}
- catch (ObjectCollectedException e) {
+ catch (ObjectCollectedException ignored) {
proxy = null;
}
catch (EvaluateException e) {
@@ -498,6 +509,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
}
SourcePosition position = PsiDocumentManager.getInstance(getProject()).commitAndRunReadAction(new Computable<SourcePosition>() {
+ @Override
public @Nullable SourcePosition compute() {
return ContextUtil.getSourcePosition(positionContext);
}
@@ -507,7 +519,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
final List<Pair<Breakpoint, Event>> eventDescriptors = DebuggerUtilsEx.getEventDescriptors(suspendContext);
final RequestManagerImpl requestsManager = suspendContext.getDebugProcess().getRequestsManager();
final PsiFile foundFile = position.getFile();
- final boolean sourceMissing = foundFile == null || foundFile instanceof PsiCompiledElement;
+ final boolean sourceMissing = foundFile instanceof PsiCompiledElement;
for (Pair<Breakpoint, Event> eventDescriptor : eventDescriptors) {
Breakpoint breakpoint = eventDescriptor.getFirst();
if (breakpoint instanceof LineBreakpoint) {
@@ -525,7 +537,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
try {
className = frameProxy != null? frameProxy.location().declaringType().name() : "";
}
- catch (EvaluateException e) {
+ catch (EvaluateException ignored) {
className = "";
}
requestsManager.setInvalid(breakpoint, DebuggerBundle.message("error.invalid.breakpoint.source.not.found", className));
@@ -539,6 +551,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
debuggerContext.setPositionCache(position);
DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
+ @Override
public void run() {
getContextManager().setState(debuggerContext, STATE_PAUSED, EVENT_PAUSE, null);
}
@@ -562,9 +575,11 @@ public class DebuggerSession implements AbstractDebuggerSession {
}
+ @Override
public void resumed(final SuspendContextImpl suspendContext) {
final SuspendContextImpl currentContext = getProcess().getSuspendManager().getPausedContext();
DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
+ @Override
public void run() {
if (currentContext != null) {
getContextManager().setState(DebuggerContextUtil.createDebuggerContext(DebuggerSession.this, currentContext), STATE_PAUSED, EVENT_CONTEXT, null);
@@ -576,6 +591,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
});
}
+ @Override
public void processAttached(final DebugProcessImpl process) {
final RemoteConnection connection = getProcess().getConnection();
final String addressDisplayName = DebuggerBundle.getAddressDisplayName(connection);
@@ -584,14 +600,17 @@ public class DebuggerSession implements AbstractDebuggerSession {
process.getExecutionResult().getProcessHandler().notifyTextAvailable(message + "\n", ProcessOutputTypes.SYSTEM);
DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
+ @Override
public void run() {
getContextManager().setState(SESSION_EMPTY_CONTEXT, STATE_RUNNING, EVENT_ATTACHED, message);
}
});
}
+ @Override
public void attachException(final RunProfileState state, final ExecutionException exception, final RemoteConnection remoteConnection) {
DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
+ @Override
public void run() {
String message = "";
if (state instanceof RemoteState) {
@@ -603,6 +622,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
});
}
+ @Override
public void processDetached(final DebugProcessImpl debugProcess, boolean closedByUser) {
if (!closedByUser) {
ExecutionResult executionResult = debugProcess.getExecutionResult();
@@ -614,6 +634,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
}
}
DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
+ @Override
public void run() {
final RemoteConnection connection = getProcess().getConnection();
final String addressDisplayName = DebuggerBundle.getAddressDisplayName(connection);
@@ -624,10 +645,12 @@ public class DebuggerSession implements AbstractDebuggerSession {
mySteppingThroughThreads.clear();
}
+ @Override
public void threadStarted(DebugProcess proc, ThreadReference thread) {
notifyThreadsRefresh();
}
+ @Override
public void threadStopped(DebugProcess proc, ThreadReference thread) {
notifyThreadsRefresh();
}
@@ -636,6 +659,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
if (!myUpdateAlarm.isDisposed()) {
myUpdateAlarm.cancelAllRequests();
myUpdateAlarm.addRequest(new Runnable() {
+ @Override
public void run() {
final DebuggerStateManager contextManager = getContextManager();
contextManager.fireStateChanged(contextManager.getContext(), EVENT_THREADS_REFRESH);
@@ -646,13 +670,16 @@ public class DebuggerSession implements AbstractDebuggerSession {
}
private class MyEvaluationListener implements EvaluationListener {
+ @Override
public void evaluationStarted(SuspendContextImpl context) {
myIsEvaluating = true;
}
+ @Override
public void evaluationFinished(final SuspendContextImpl context) {
myIsEvaluating = false;
DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
+ @Override
public void run() {
if (context != getSuspendContext()) {
getContextManager().setState(DebuggerContextUtil.createDebuggerContext(DebuggerSession.this, context), STATE_PAUSED, EVENT_REFRESH, null);
diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java
index 4ff1adcabda4..5fed47929af3 100644
--- a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java
@@ -70,7 +70,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
clearCaches();
}
catch (InternalException e) {
- if (e.errorCode() == 23 /*INVALID_METHODID accoeding to JDI sources*/) {
+ if (e.errorCode() == 23 /*INVALID_METHODID according to JDI sources*/) {
myIsObsolete = Boolean.TRUE;
return true;
}
@@ -83,6 +83,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
return false;
}
+ @Override
protected void clearCaches() {
DebuggerManagerThreadImpl.assertIsManagerThread();
if (LOG.isDebugEnabled()) {
@@ -100,6 +101,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
* Use with caution. Better access stackframe data through the Proxy's methods
*/
+ @Override
public StackFrame getStackFrame() throws EvaluateException {
DebuggerManagerThreadImpl.assertIsManagerThread();
@@ -113,7 +115,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
catch (IndexOutOfBoundsException e) {
throw new EvaluateException(e.getMessage(), e);
}
- catch (ObjectCollectedException e) {
+ catch (ObjectCollectedException ignored) {
throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.thread.collected"));
}
catch (IncompatibleThreadStateException e) {
@@ -124,6 +126,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
return myStackFrame;
}
+ @Override
public int getFrameIndex() throws EvaluateException {
DebuggerManagerThreadImpl.assertIsManagerThread();
checkValid();
@@ -151,10 +154,13 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
// return false;
// }
+ @Override
public VirtualMachineProxyImpl getVirtualMachine() {
return (VirtualMachineProxyImpl) myTimer;
}
+ @Nullable
+ @Override
public Location location() throws EvaluateException {
InvalidStackFrameException error = null;
for (int attempt = 0; attempt < 2; attempt++) {
@@ -172,6 +178,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
return null;
}
+ @Override
public ThreadReferenceProxyImpl threadProxy() {
return myThreadProxy;
}
@@ -197,13 +204,13 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
}
break;
}
- catch (InvalidStackFrameException e) {
+ catch (InvalidStackFrameException ignored) {
clearCaches();
}
}
}
catch (InternalException e) {
- // supress some internal errors caused by bugs in specific JDI implementations
+ // suppress some internal errors caused by bugs in specific JDI implementations
if(e.errorCode() != 23) {
throw EvaluateExceptionUtil.createEvaluateException(e);
}
@@ -238,6 +245,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
return Collections.emptyList();
}
+ @Override
public LocalVariableProxyImpl visibleVariableByName(String name) throws EvaluateException {
DebuggerManagerThreadImpl.assertIsManagerThread();
final LocalVariable variable = visibleVariableByNameInt(name);
@@ -332,7 +340,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
myAllValues.put(variable, value);
}
}
- catch (InconsistentDebugInfoException e) {
+ catch (InconsistentDebugInfoException ignored) {
clearCaches();
throw EvaluateExceptionUtil.INCONSISTEND_DEBUG_INFO;
}
@@ -388,12 +396,13 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
try {
return var.getVariable().isVisible(getStackFrame());
}
- catch (IllegalArgumentException e) {
+ catch (IllegalArgumentException ignored) {
// can be thrown if frame's method is different than variable's method
return false;
}
}
+ @Override
public ClassLoaderReference getClassLoader() throws EvaluateException {
if(myClassLoader == null) {
myClassLoader = location().declaringType().classLoader();
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java
index 5eb71c30e869..1395654a06d1 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java
@@ -73,8 +73,6 @@ public abstract class DebuggerEditorImpl extends CompletionEditor{
private final JLabel myChooseFactory = new JLabel();
private WeakReference<ListPopup> myPopup;
- private boolean myExplicitlyChosen = false;
-
private final PsiTreeChangeListener myPsiListener = new PsiTreeChangeAdapter() {
public void childRemoved(@NotNull PsiTreeChangeEvent event) {
checkContext();
@@ -142,7 +140,6 @@ public abstract class DebuggerEditorImpl extends CompletionEditor{
@Override
public void actionPerformed(AnActionEvent e) {
setFactory(fragmentFactory);
- myExplicitlyChosen = true;
setText(getText());
IdeFocusManager.getInstance(getProject()).requestFocus(DebuggerEditorImpl.this, true);
}
@@ -300,33 +297,12 @@ public abstract class DebuggerEditorImpl extends CompletionEditor{
return DefaultCodeFragmentFactory.getInstance();
}
- @NotNull
- private CodeFragmentFactory findFactoryForRestore(@NotNull TextWithImports text, @NotNull PsiElement context) {
- List<CodeFragmentFactory> factories = DebuggerUtilsEx.getCodeFragmentFactories(context);
-
- if (myExplicitlyChosen && factories.contains(myFactory)) return myFactory;
-
- DefaultCodeFragmentFactory defaultFactory = DefaultCodeFragmentFactory.getInstance();
- factories.remove(defaultFactory);
- for (CodeFragmentFactory factory : factories) {
- if (factory.getFileType().equals(text.getFileType())) {
- return factory;
- }
- }
- if (!factories.isEmpty()) return factories.get(0);
- else return defaultFactory;
- }
-
protected void restoreFactory(TextWithImports text) {
FileType fileType = text.getFileType();
if (fileType == null) return;
if (myContext == null) return;
- CodeFragmentFactory newFactory = findFactoryForRestore(text, myContext);
- if (!newFactory.equals(myFactory)) {
- myExplicitlyChosen = false;
- setFactory(newFactory);
- }
+ setFactory(findAppropriateFactory(text, myContext));
}
private void setFactory(@NotNull final CodeFragmentFactory factory) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java
index e021d76b271b..46f1515f1ea5 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java
@@ -19,19 +19,17 @@ import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.actions.*;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.settings.*;
-import com.intellij.debugger.ui.breakpoints.*;
+import com.intellij.debugger.ui.breakpoints.Breakpoint;
import com.intellij.ide.DataManager;
import com.intellij.openapi.Disposable;
-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.editor.Document;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
-import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Key;
-import com.intellij.util.containers.ContainerUtil;
import com.intellij.xdebugger.AbstractDebuggerSession;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
import com.intellij.xdebugger.impl.DebuggerSupport;
@@ -45,9 +43,10 @@ import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
import com.intellij.xdebugger.impl.settings.DebuggerSettingsPanelProvider;
import org.jetbrains.annotations.NotNull;
+import javax.swing.*;
+import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
/**
* @author nik
@@ -63,8 +62,6 @@ public class JavaDebuggerSupport extends DebuggerSupport {
private final ForceRunToCursorActionHandler myForceRunToCursorActionHandler = new ForceRunToCursorActionHandler();
private final ResumeActionHandler myResumeActionHandler = new ResumeActionHandler();
private final PauseActionHandler myPauseActionHandler = new PauseActionHandler();
- private final ToggleLineBreakpointActionHandler myToggleLineBreakpointActionHandler = new ToggleLineBreakpointActionHandler(false);
- private final ToggleLineBreakpointActionHandler myToggleTemporaryLineBreakpointActionHandler = new ToggleLineBreakpointActionHandler(true);
private final ShowExecutionPointActionHandler myShowExecutionPointActionHandler = new ShowExecutionPointActionHandler();
private final EvaluateActionHandler myEvaluateActionHandler = new EvaluateActionHandler();
private final QuickEvaluateActionHandler myQuickEvaluateHandler = new QuickEvaluateActionHandler();
@@ -73,84 +70,98 @@ public class JavaDebuggerSupport extends DebuggerSupport {
private final DebuggerActionHandler mySmartStepIntoHandler = new JvmSmartStepIntoActionHandler();
private final DebuggerActionHandler myAddToWatchedActionHandler = new AddToWatchActionHandler();
private final JavaMarkObjectActionHandler myMarkObjectActionHandler = new JavaMarkObjectActionHandler();
- private final JavaEditBreakpointActionHandler myEditBreakpointActionHandler = new JavaEditBreakpointActionHandler();
+ @Override
@NotNull
public BreakpointPanelProvider<?> getBreakpointPanelProvider() {
return myBreakpointPanelProvider;
}
+ @Override
@NotNull
public DebuggerActionHandler getStepOverHandler() {
return myStepOverActionHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getStepIntoHandler() {
return myStepIntoActionHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getSmartStepIntoHandler() {
return mySmartStepIntoHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getStepOutHandler() {
return myStepOutActionHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getForceStepOverHandler() {
return myForceStepOverActionHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getForceStepIntoHandler() {
return myForceStepIntoActionHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getRunToCursorHandler() {
return myRunToCursorActionHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getForceRunToCursorHandler() {
return myForceRunToCursorActionHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getResumeActionHandler() {
return myResumeActionHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getPauseHandler() {
return myPauseActionHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getToggleLineBreakpointHandler() {
- return myToggleLineBreakpointActionHandler;
+ return DISABLED;
}
@NotNull
@Override
public DebuggerActionHandler getToggleTemporaryLineBreakpointHandler() {
- return myToggleTemporaryLineBreakpointActionHandler;
+ return DISABLED;
}
+ @Override
@NotNull
public DebuggerActionHandler getShowExecutionPointHandler() {
return myShowExecutionPointActionHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getEvaluateHandler() {
return myEvaluateActionHandler;
}
+ @Override
@NotNull
public QuickEvaluateHandler getQuickEvaluateHandler() {
return myQuickEvaluateHandler;
@@ -162,6 +173,7 @@ public class JavaDebuggerSupport extends DebuggerSupport {
return myAddToWatchedActionHandler;
}
+ @Override
@NotNull
public DebuggerToggleActionHandler getMuteBreakpointsHandler() {
return myMuteBreakpointsHandler;
@@ -182,134 +194,141 @@ public class JavaDebuggerSupport extends DebuggerSupport {
@NotNull
@Override
public EditBreakpointActionHandler getEditBreakpointAction() {
- return myEditBreakpointActionHandler;
+ return DISABLED_EDIT;
}
+ @Override
@NotNull
public DebuggerSettingsPanelProvider getSettingsPanelProvider() {
return myDebuggerSettingsPanelProvider;
}
private static class JavaBreakpointPanelProvider extends BreakpointPanelProvider<Breakpoint> {
- private final List<MyBreakpointManagerListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ //private final List<MyBreakpointManagerListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
@Override
public AnAction[] getAddBreakpointActions(@NotNull Project project) {
- List<AnAction> result = new ArrayList<AnAction>();
- BreakpointFactory[] breakpointFactories = BreakpointFactory.getBreakpointFactories();
- for (BreakpointFactory breakpointFactory : breakpointFactories) {
- result.add(new AddJavaBreakpointAction(breakpointFactory));
- }
- return result.toArray(new AnAction[result.size()]);
+ //List<AnAction> result = new ArrayList<AnAction>();
+ //BreakpointFactory[] breakpointFactories = BreakpointFactory.getBreakpointFactories();
+ //for (BreakpointFactory breakpointFactory : breakpointFactories) {
+ // result.add(new AddJavaBreakpointAction(breakpointFactory));
+ //}
+ //return result.toArray(new AnAction[result.size()]);
+ return AnAction.EMPTY_ARRAY;
}
@Override
public void createBreakpointsGroupingRules(Collection<XBreakpointGroupingRule> rules) {
- rules.add(new XBreakpointGroupingByCategoryRule());
+ //rules.add(new XBreakpointGroupingByCategoryRule());
rules.add(new XBreakpointGroupingByPackageRule());
rules.add(new XBreakpointGroupingByClassRule());
}
@Override
public void addListener(final BreakpointsListener listener, Project project, Disposable disposable) {
- BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager();
- final MyBreakpointManagerListener listener1 = new MyBreakpointManagerListener(listener, breakpointManager);
- breakpointManager.addBreakpointManagerListener(listener1);
- myListeners.add(listener1);
- Disposer.register(disposable, new Disposable() {
- @Override
- public void dispose() {
- removeListener(listener);
- }
- });
+ //BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager();
+ //final MyBreakpointManagerListener listener1 = new MyBreakpointManagerListener(listener, breakpointManager);
+ //breakpointManager.addBreakpointManagerListener(listener1);
+ //myListeners.add(listener1);
+ //Disposer.register(disposable, new Disposable() {
+ // @Override
+ // public void dispose() {
+ // removeListener(listener);
+ // }
+ //});
}
@Override
protected void removeListener(BreakpointsListener listener) {
- for (MyBreakpointManagerListener managerListener : myListeners) {
- if (managerListener.myListener == listener) {
- BreakpointManager manager = managerListener.myBreakpointManager;
- manager.removeBreakpointManagerListener(managerListener);
- myListeners.remove(managerListener);
- break;
- }
- }
+ //for (MyBreakpointManagerListener managerListener : myListeners) {
+ // if (managerListener.myListener == listener) {
+ // BreakpointManager manager = managerListener.myBreakpointManager;
+ // manager.removeBreakpointManagerListener(managerListener);
+ // myListeners.remove(managerListener);
+ // break;
+ // }
+ //}
}
+ @Override
public int getPriority() {
- return 1;
+ return 100;
}
+ @Override
public Breakpoint findBreakpoint(@NotNull final Project project, @NotNull final Document document, final int offset) {
- return DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().findBreakpoint(document, offset, null);
+ return null;
+ //return DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().findBreakpoint(document, offset, null);
}
@Override
public GutterIconRenderer getBreakpointGutterIconRenderer(Object breakpoint) {
- if (breakpoint instanceof BreakpointWithHighlighter) {
- final RangeHighlighter highlighter = ((BreakpointWithHighlighter)breakpoint).getHighlighter();
- if (highlighter != null) {
- return (GutterIconRenderer)highlighter.getGutterIconRenderer();
- }
- }
+ //if (breakpoint instanceof BreakpointWithHighlighter) {
+ // final RangeHighlighter highlighter = ((BreakpointWithHighlighter)breakpoint).getHighlighter();
+ // if (highlighter != null) {
+ // return (GutterIconRenderer)highlighter.getGutterIconRenderer();
+ // }
+ //}
return null;
}
+ @Override
public void onDialogClosed(final Project project) {
- DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().updateAllRequests();
+ //DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().updateAllRequests();
}
@Override
public void provideBreakpointItems(Project project, Collection<BreakpointItem> items) {
- for (BreakpointFactory breakpointFactory : BreakpointFactory.getBreakpointFactories()) {
- Key<? extends Breakpoint> category = breakpointFactory.getBreakpointCategory();
- Breakpoint[] breakpoints = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().getBreakpoints(category);
- for (Breakpoint breakpoint : breakpoints) {
- items.add(breakpointFactory.createBreakpointItem(breakpoint));
- }
- }
+ //for (BreakpointFactory breakpointFactory : BreakpointFactory.getBreakpointFactories()) {
+ // Key<? extends Breakpoint> category = breakpointFactory.getBreakpointCategory();
+ // Breakpoint[] breakpoints = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().getBreakpoints(category);
+ // for (Breakpoint breakpoint : breakpoints) {
+ // items.add(breakpointFactory.createBreakpointItem(breakpoint));
+ // }
+ //}
}
- private static class AddJavaBreakpointAction extends AnAction {
- private BreakpointFactory myBreakpointFactory;
-
- public AddJavaBreakpointAction(BreakpointFactory breakpointFactory) {
- myBreakpointFactory = breakpointFactory;
- Presentation p = getTemplatePresentation();
- p.setIcon(myBreakpointFactory.getIcon());
- p.setText(breakpointFactory.getDisplayName());
- }
-
- @Override
- public void update(AnActionEvent e) {
- e.getPresentation().setVisible(myBreakpointFactory.canAddBreakpoints());
- }
-
- @Override
- public void actionPerformed(AnActionEvent e) {
- myBreakpointFactory.addBreakpoint(getEventProject(e));
- }
- }
-
- private static class MyBreakpointManagerListener implements BreakpointManagerListener {
-
- private final BreakpointsListener myListener;
- public BreakpointManager myBreakpointManager;
-
-
- public MyBreakpointManagerListener(BreakpointsListener listener, BreakpointManager breakpointManager) {
- myListener = listener;
- myBreakpointManager = breakpointManager;
- }
-
- @Override
- public void breakpointsChanged() {
- myListener.breakpointsChanged();
- }
- }
+ //private static class AddJavaBreakpointAction extends AnAction {
+ // private BreakpointFactory myBreakpointFactory;
+ //
+ // public AddJavaBreakpointAction(BreakpointFactory breakpointFactory) {
+ // myBreakpointFactory = breakpointFactory;
+ // Presentation p = getTemplatePresentation();
+ // p.setIcon(myBreakpointFactory.getIcon());
+ // p.setText(breakpointFactory.getDisplayName());
+ // }
+ //
+ // @Override
+ // public void update(AnActionEvent e) {
+ // e.getPresentation().setVisible(myBreakpointFactory.canAddBreakpoints());
+ // }
+ //
+ // @Override
+ // public void actionPerformed(AnActionEvent e) {
+ // myBreakpointFactory.addBreakpoint(getEventProject(e));
+ // }
+ //}
+
+ //private static class MyBreakpointManagerListener implements BreakpointManagerListener {
+ //
+ // private final BreakpointsListener myListener;
+ // public BreakpointManager myBreakpointManager;
+ //
+ //
+ // public MyBreakpointManagerListener(BreakpointsListener listener, BreakpointManager breakpointManager) {
+ // myListener = listener;
+ // myBreakpointManager = breakpointManager;
+ // }
+ //
+ // @Override
+ // public void breakpointsChanged() {
+ // myListener.breakpointsChanged();
+ // }
+ //}
}
public static class JavaDebuggerSettingsPanelProvider extends DebuggerSettingsPanelProvider {
+ @Override
public int getPriority() {
return 1;
}
@@ -319,6 +338,7 @@ public class JavaDebuggerSupport extends DebuggerSupport {
return new DebuggerLaunchingConfigurable();
}
+ @Override
public Collection<? extends Configurable> getConfigurables() {
final ArrayList<Configurable> configurables = new ArrayList<Configurable>();
configurables.add(new DebuggerDataViewsConfigurable(null));
@@ -328,6 +348,7 @@ public class JavaDebuggerSupport extends DebuggerSupport {
return configurables;
}
+ @Override
public void apply() {
NodeRendererSettings.getInstance().fireRenderersChanged();
}
@@ -341,4 +362,27 @@ public class JavaDebuggerSupport extends DebuggerSupport {
}
return ProjectManager.getInstance().getDefaultProject();
}
+
+ private static final DebuggerActionHandler DISABLED = new DebuggerActionHandler() {
+ @Override
+ public void perform(@NotNull Project project, AnActionEvent event) {
+ }
+
+ @Override
+ public boolean isEnabled(@NotNull Project project, AnActionEvent event) {
+ return false;
+ }
+ };
+
+ private static final EditBreakpointActionHandler DISABLED_EDIT = new EditBreakpointActionHandler() {
+ @Override
+ protected void doShowPopup(Project project, JComponent component, Point whereToShow, Object breakpoint) {
+
+ }
+
+ @Override
+ public boolean isEnabled(@NotNull Project project, AnActionEvent event) {
+ return false;
+ }
+ };
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java b/java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java
index e5bb8faafb61..dd0b0de43151 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/PositionHighlighter.java
@@ -437,7 +437,7 @@ public class PositionHighlighter {
public void actionPerformed(AnActionEvent e) {
if (myEventsOutOfLine.size() == 1) {
Breakpoint breakpoint = myEventsOutOfLine.get(0).getFirst();
- breakpoint.ENABLED = !breakpoint.ENABLED;
+ breakpoint.setEnabled(!breakpoint.isEnabled());
DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().fireBreakpointChanged(breakpoint);
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java
deleted file mode 100644
index 032b480c5584..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java
+++ /dev/null
@@ -1,81 +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.debugger.ui;
-
-import com.intellij.debugger.ui.breakpoints.Breakpoint;
-import com.intellij.debugger.ui.breakpoints.BreakpointFactory;
-import com.intellij.openapi.util.Key;
-import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup;
-import com.intellij.xdebugger.impl.breakpoints.ui.grouping.XBreakpointTypeGroup;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-
-/**
- * Created with IntelliJ IDEA.
- * User: zajac
- * Date: 23.05.12
- * Time: 16:22
- * To change this template use File | Settings | File Templates.
- */
-public class XBreakpointCategoryGroup extends XBreakpointGroup {
- private Key<? extends Breakpoint> myCategory;
- private Icon myIcon;
- private final String myName;
-
- public XBreakpointCategoryGroup(BreakpointFactory factory) {
- myCategory = factory.getBreakpointCategory();
- myIcon = factory.getIcon();
- final String name = factory.getDisplayName();
- myName = name != null ? name : "UNKNOWN";
- }
-
- public Key<? extends Breakpoint> getCategory() {
- return myCategory;
- }
-
- @Override
- public Icon getIcon(boolean isOpen) {
- return myIcon;
- }
-
- @NotNull
- @Override
- public String getName() {
- return myName;
- }
-
- @Override
- public int compareTo(XBreakpointGroup o) {
- if (o instanceof XBreakpointTypeGroup) {
- return -1;
- }
- if (o instanceof XBreakpointCategoryGroup) {
- return getFactoryIndex() - ((XBreakpointCategoryGroup)o).getFactoryIndex();
- }
- return super.compareTo(o);
- }
-
- private int getFactoryIndex() {
- BreakpointFactory[] breakpointFactories = BreakpointFactory.getBreakpointFactories();
- for (int i = 0; i < breakpointFactories.length; ++i) {
- if (breakpointFactories[i].getBreakpointCategory().equals(myCategory)) {
- return i;
- }
- }
- return -1;
- }
-}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java
deleted file mode 100644
index f9dc88af07ac..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java
+++ /dev/null
@@ -1,64 +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.debugger.ui;
-
-import com.intellij.debugger.ui.breakpoints.AnyExceptionBreakpoint;
-import com.intellij.debugger.ui.breakpoints.Breakpoint;
-import com.intellij.debugger.ui.breakpoints.BreakpointFactory;
-import com.intellij.debugger.ui.breakpoints.ExceptionBreakpoint;
-import com.intellij.openapi.util.Key;
-import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
-import com.intellij.xdebugger.breakpoints.ui.XBreakpointsGroupingPriorities;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Collection;
-
-class XBreakpointGroupingByCategoryRule<B> extends XBreakpointGroupingRule<B, XBreakpointCategoryGroup> {
- XBreakpointGroupingByCategoryRule() {
- super("XBreakpointGroupingByCategoryRule", "Type");
- }
-
- @Override
- public boolean isAlwaysEnabled() {
- return true;
- }
-
- @Override
- public int getPriority() {
- return XBreakpointsGroupingPriorities.BY_TYPE;
- }
-
- @Override
- public XBreakpointCategoryGroup getGroup(@NotNull B b, @NotNull Collection<XBreakpointCategoryGroup> groups) {
- if (b instanceof Breakpoint) {
- final Breakpoint breakpoint = (Breakpoint)b;
- Key<? extends Breakpoint> category = breakpoint.getCategory();
- if (category.equals(AnyExceptionBreakpoint.ANY_EXCEPTION_BREAKPOINT)) {
- category = ExceptionBreakpoint.CATEGORY;
- }
- for (XBreakpointCategoryGroup group : groups) {
- if (group.getCategory().equals(category)) {
- return group;
- }
- }
- final BreakpointFactory factory = BreakpointFactory.getInstance(category);
- if (factory != null) {
- return new XBreakpointCategoryGroup(factory);
- }
- }
- return null;
- }
-}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java
index f06a17ef0727..cebaf68612a0 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java
@@ -15,8 +15,11 @@
*/
package com.intellij.debugger.ui;
+import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.ui.breakpoints.Breakpoint;
+import com.intellij.debugger.ui.breakpoints.BreakpointManager;
import com.intellij.icons.AllIcons;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointsGroupingPriorities;
import org.jetbrains.annotations.NotNull;
@@ -42,10 +45,14 @@ class XBreakpointGroupingByClassRule<B> extends XBreakpointGroupingRule<B, XBrea
@Override
public XBreakpointClassGroup getGroup(@NotNull B b, @NotNull Collection<XBreakpointClassGroup> groups) {
- if (b instanceof Breakpoint) {
- final Breakpoint breakpoint = (Breakpoint)b;
- String className = breakpoint.getShortClassName();
- String packageName = breakpoint.getPackageName();
+ if (b instanceof XBreakpoint) {
+ BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(JavaDebuggerSupport.getCurrentProject()).getBreakpointManager();
+ Breakpoint javaBreakpoint = breakpointManager.findBreakpoint((XBreakpoint)b);
+ if (javaBreakpoint == null) {
+ return null;
+ }
+ String className = javaBreakpoint.getShortClassName();
+ String packageName = javaBreakpoint.getPackageName();
if (className == null) {
return null;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java
index 5763a3648f64..98ef5a3409ec 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java
@@ -15,10 +15,12 @@
*/
package com.intellij.debugger.ui;
-import com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter;
-import com.intellij.debugger.ui.breakpoints.ExceptionBreakpoint;
+import com.intellij.debugger.DebuggerManagerEx;
+import com.intellij.debugger.ui.breakpoints.Breakpoint;
+import com.intellij.debugger.ui.breakpoints.BreakpointManager;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointsGroupingPriorities;
import org.jetbrains.annotations.NotNull;
@@ -41,11 +43,12 @@ public class XBreakpointGroupingByPackageRule<B> extends XBreakpointGroupingRule
@Override
public XBreakpointPackageGroup getGroup(@NotNull B breakpoint, @NotNull Collection<XBreakpointPackageGroup> groups) {
String packageName = null;
- if (breakpoint instanceof BreakpointWithHighlighter) {
- packageName = ((BreakpointWithHighlighter)breakpoint).getPackageName();
- }
- else if (breakpoint instanceof ExceptionBreakpoint) {
- packageName = ((ExceptionBreakpoint)breakpoint).getPackageName();
+ if (breakpoint instanceof XBreakpoint) {
+ BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(JavaDebuggerSupport.getCurrentProject()).getBreakpointManager();
+ Breakpoint javaBreakpoint = breakpointManager.findBreakpoint((XBreakpoint)breakpoint);
+ if (javaBreakpoint != null) {
+ packageName = javaBreakpoint.getPackageName();
+ }
}
if (packageName == null) {
return null;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java
index f325da10fcde..e3cd5229e0ab 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddFieldBreakpointDialog.java
@@ -41,7 +41,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
-abstract class AddFieldBreakpointDialog extends DialogWrapper {
+public abstract class AddFieldBreakpointDialog extends DialogWrapper {
private final Project myProject;
private JPanel myPanel;
private TextFieldWithBrowseButton myFieldChooser;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddWildcardBreakpointDialog.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddWildcardBreakpointDialog.java
index c18acb715935..73c74a4eed0a 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddWildcardBreakpointDialog.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AddWildcardBreakpointDialog.java
@@ -30,7 +30,7 @@ public class AddWildcardBreakpointDialog extends DialogWrapper {
private JTextField myClassPatternField;
private JTextField myMethodNameField;
- protected AddWildcardBreakpointDialog(Project project) {
+ public AddWildcardBreakpointDialog(Project project) {
super(project, true);
setTitle("Add Method Breakpoint");
init();
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java
index 3d1ff8507d10..8787290c2f09 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java
@@ -27,6 +27,7 @@ import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.Key;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.sun.jdi.ReferenceType;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -34,9 +35,9 @@ import org.jetbrains.annotations.NonNls;
public class AnyExceptionBreakpoint extends ExceptionBreakpoint {
public static final @NonNls Key<AnyExceptionBreakpoint> ANY_EXCEPTION_BREAKPOINT = BreakpointCategory.lookup("breakpoint_any");
- protected AnyExceptionBreakpoint(Project project) {
- super(project, null, null);
- ENABLED = false;
+ protected AnyExceptionBreakpoint(Project project, XBreakpoint xBreakpoint) {
+ super(project, null, null, xBreakpoint);
+ //setEnabled(false);
}
public Key<AnyExceptionBreakpoint> getCategory() {
@@ -49,7 +50,7 @@ public class AnyExceptionBreakpoint extends ExceptionBreakpoint {
public void createRequest(DebugProcessImpl debugProcess) {
DebuggerManagerThreadImpl.assertIsManagerThread();
- if (!ENABLED || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) {
+ if (!isEnabled() || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) {
return;
}
super.processClassPrepare(debugProcess, null);
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java
deleted file mode 100644
index f595c1d81c65..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpointFactory.java
+++ /dev/null
@@ -1,65 +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.ui.breakpoints;
-
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Key;
-import org.jdom.Element;
-
-import javax.swing.*;
-
-/**
- * @author Eugene Zhuravlev
- * Date: Apr 26, 2005
- */
-public class AnyExceptionBreakpointFactory extends BreakpointFactory{
- public Breakpoint createBreakpoint(Project project, final Element element) {
- return new AnyExceptionBreakpoint(project);
- }
-
- public Icon getIcon() {
- return AllIcons.Debugger.Db_exception_breakpoint;
- }
-
- public Icon getDisabledIcon() {
- return AllIcons.Debugger.Db_disabled_exception_breakpoint;
- }
-
- @Override
- protected String getHelpID() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public String getDisplayName() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact) {
- return new ExceptionBreakpointPropertiesPanel(project, compact);
- }
-
- @Override
- public boolean breakpointCanBeRemoved(Breakpoint breakpoint) {
- return false;
- }
-
- public Key<AnyExceptionBreakpoint> getBreakpointCategory() {
- return AnyExceptionBreakpoint.ANY_EXCEPTION_BREAKPOINT;
- }
-}
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 1b370ca47ded..bbbcf8ef1265 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
@@ -30,45 +30,62 @@ import com.intellij.debugger.engine.requests.RequestManagerImpl;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.debugger.requests.ClassPrepareRequestor;
+import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizerUtil;
import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
import com.intellij.ui.AppUIUtil;
+import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.util.StringBuilderSpinAllocator;
-import com.sun.jdi.ObjectReference;
-import com.sun.jdi.ReferenceType;
-import com.sun.jdi.Value;
-import com.sun.jdi.VoidValue;
+import com.intellij.xdebugger.breakpoints.SuspendPolicy;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
+import com.sun.jdi.*;
import com.sun.jdi.event.LocatableEvent;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties;
import javax.swing.*;
import java.util.List;
-public abstract class Breakpoint extends FilteredRequestor implements ClassPrepareRequestor {
- public boolean ENABLED = true;
- public boolean LOG_ENABLED = false;
- public boolean LOG_EXPRESSION_ENABLED = false;
- public boolean REMOVE_AFTER_HIT = false;
- private TextWithImports myLogMessage; // an expression to be evaluated and printed
+public abstract class Breakpoint<P extends JavaBreakpointProperties> implements FilteredRequestor, ClassPrepareRequestor {
+ final XBreakpoint<P> myXBreakpoint;
+ protected final Project myProject;
+
+ //private boolean ENABLED = true;
+ //private boolean LOG_ENABLED = false;
+ //private boolean LOG_EXPRESSION_ENABLED = false;
+ //private boolean REMOVE_AFTER_HIT = false;
+ //private TextWithImports myLogMessage; // an expression to be evaluated and printed
@NonNls private static final String LOG_MESSAGE_OPTION_NAME = "LOG_MESSAGE";
public static final Breakpoint[] EMPTY_ARRAY = new Breakpoint[0];
protected boolean myCachedVerifiedState = false;
+ //private TextWithImportsImpl myLogMessage;
- protected Breakpoint(@NotNull Project project) {
- super(project);
- myLogMessage = new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "");
+ protected Breakpoint(@NotNull Project project, XBreakpoint<P> xBreakpoint) {
+ //super(project);
+ myProject = project;
+ myXBreakpoint = xBreakpoint;
+ //myLogMessage = new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "");
//noinspection AbstractMethodCallInConstructor
- final BreakpointDefaults defaults = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().getBreakpointDefaults(getCategory());
- SUSPEND_POLICY = defaults.getSuspendPolicy();
- CONDITION_ENABLED = defaults.isConditionEnabled();
+ //final BreakpointDefaults defaults = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().getBreakpointDefaults(getCategory());
+ //SUSPEND_POLICY = defaults.getSuspendPolicy();
+ //CONDITION_ENABLED = defaults.isConditionEnabled();
+ }
+
+ public Project getProject() {
+ return myProject;
+ }
+
+ protected P getProperties() {
+ return myXBreakpoint.getProperties();
}
public abstract PsiClass getPsiClass();
@@ -100,6 +117,16 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa
myCachedVerifiedState = isVerified;
}
+ public boolean isRemoveAfterHit() {
+ return myXBreakpoint instanceof XLineBreakpoint && ((XLineBreakpoint)myXBreakpoint).isTemporary();
+ }
+
+ public void setRemoveAfterHit(boolean value) {
+ if (myXBreakpoint instanceof XLineBreakpoint) {
+ ((XLineBreakpoint)myXBreakpoint).setTemporary(value);
+ }
+ }
+
@Nullable
public String getShortClassName() {
final String className = getClassName();
@@ -210,19 +237,19 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa
private void runAction(final EvaluationContextImpl context, LocatableEvent event) {
final DebugProcessImpl debugProcess = context.getDebugProcess();
- if (LOG_ENABLED || LOG_EXPRESSION_ENABLED) {
+ if (isLogEnabled() || isLogExpressionEnabled()) {
final StringBuilder buf = StringBuilderSpinAllocator.alloc();
try {
- if (LOG_ENABLED) {
+ if (myXBreakpoint.isLogMessage()) {
buf.append(getEventMessage(event));
buf.append("\n");
}
- final TextWithImports expressionToEvaluate = getLogMessage();
- if (LOG_EXPRESSION_ENABLED && expressionToEvaluate != null && !"".equals(expressionToEvaluate.getText())) {
+ if (isLogExpressionEnabled()) {
if(!debugProcess.isAttached()) {
return;
}
-
+
+ final TextWithImports expressionToEvaluate = getLogMessage();
try {
ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(getProject(), new EvaluatingComputable<ExpressionEvaluator>() {
@Override
@@ -252,11 +279,112 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa
StringBuilderSpinAllocator.dispose(buf);
}
}
- if (REMOVE_AFTER_HIT) {
+ if (isRemoveAfterHit()) {
handleTemporaryBreakpointHit(debugProcess);
}
}
+ /**
+ * @return true if the ID was added or false otherwise
+ */
+ private boolean hasObjectID(long id) {
+ for (InstanceFilter instanceFilter : getInstanceFilters()) {
+ if (instanceFilter.getId() == id) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean evaluateCondition(final EvaluationContextImpl context, LocatableEvent event) throws EvaluateException {
+ if(isCountFilterEnabled()) {
+ final DebugProcessImpl debugProcess = context.getDebugProcess();
+ debugProcess.getVirtualMachineProxy().suspend();
+ debugProcess.getRequestsManager().deleteRequest(this);
+ ((Breakpoint)this).createRequest(debugProcess);
+ debugProcess.getVirtualMachineProxy().resume();
+ }
+ if (isInstanceFiltersEnabled()) {
+ Value value = context.getThisObject();
+ if (value != null) { // non-static
+ ObjectReference reference = (ObjectReference)value;
+ if(!hasObjectID(reference.uniqueID())) {
+ return false;
+ }
+ }
+ }
+
+ if (isClassFiltersEnabled()) {
+ String typeName = calculateEventClass(context, event);
+ if (!typeMatchesClassFilters(typeName)) return false;
+ }
+
+ if (isConditionEnabled() && !getCondition().getText().isEmpty()) {
+ try {
+ ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(context.getProject(), new EvaluatingComputable<ExpressionEvaluator>() {
+ public ExpressionEvaluator compute() throws EvaluateException {
+ final SourcePosition contextSourcePosition = ContextUtil.getSourcePosition(context);
+ // IMPORTANT: calculate context psi element basing on the location where the exception
+ // has been hit, not on the location where it was set. (For line breakpoints these locations are the same, however,
+ // for method, exception and field breakpoints these locations differ)
+ PsiElement contextPsiElement = ContextUtil.getContextElement(contextSourcePosition);
+ if (contextPsiElement == null) {
+ contextPsiElement = getEvaluationElement(); // as a last resort
+ }
+ return EvaluatorBuilderImpl.build(getCondition(), contextPsiElement, contextSourcePosition);
+ }
+ });
+ final Value value = evaluator.evaluate(context);
+ if (!(value instanceof BooleanValue)) {
+ throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.boolean.expected"));
+ }
+ if(!((BooleanValue)value).booleanValue()) {
+ return false;
+ }
+ }
+ catch (EvaluateException ex) {
+ if(ex.getCause() instanceof VMDisconnectedException) {
+ return false;
+ }
+ throw EvaluateExceptionUtil.createEvaluateException(
+ DebuggerBundle.message("error.failed.evaluating.breakpoint.condition", getCondition(), ex.getMessage())
+ );
+ }
+ return true;
+ }
+
+ return true;
+ }
+
+ protected String calculateEventClass(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException {
+ return event.location().declaringType().name();
+ }
+
+ private boolean typeMatchesClassFilters(@Nullable String typeName) {
+ if (typeName == null) {
+ return true;
+ }
+ boolean matches = false, hasEnabled = false;
+ for (ClassFilter classFilter : getClassFilters()) {
+ if (classFilter.isEnabled()) {
+ hasEnabled = true;
+ if (classFilter.matches(typeName)) {
+ matches = true;
+ break;
+ }
+ }
+ }
+ if(hasEnabled && !matches) {
+ return false;
+ }
+ for (ClassFilter classFilter : getClassExclusionFilters()) {
+ if (classFilter.isEnabled() && classFilter.matches(typeName)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
private void handleTemporaryBreakpointHit(final DebugProcessImpl debugProcess) {
debugProcess.addDebugProcessListener(new DebugProcessAdapter() {
@Override
@@ -288,26 +416,213 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa
RequestManagerImpl.deleteRequests(this);
}
- @Override
public void readExternal(Element parentNode) throws InvalidDataException {
- super.readExternal(parentNode);
- String logMessage = JDOMExternalizerUtil.readField(parentNode, LOG_MESSAGE_OPTION_NAME);
- if (logMessage != null) {
- setLogMessage(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, logMessage));
+ FilteredRequestorImpl requestor = new FilteredRequestorImpl(myProject);
+ requestor.readTo(parentNode, this);
+ try {
+ setEnabled(Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "ENABLED")));
+ } catch (Exception e) {
}
+ try {
+ setLogEnabled(Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "LOG_ENABLED")));
+ } catch (Exception e) {
+ }
+ try {
+ if (Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "LOG_EXPRESSION_ENABLED"))) {
+ String logMessage = JDOMExternalizerUtil.readField(parentNode, LOG_MESSAGE_OPTION_NAME);
+ if (logMessage != null) {
+ setLogMessage(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, logMessage));
+ }
+ }
+ } catch (Exception e) {
+ }
+ try {
+ setRemoveAfterHit(Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "REMOVE_AFTER_HIT")));
+ } catch (Exception e) {
+ }
+ }
+
+ //@Override
+ //public void writeExternal(Element parentNode) throws WriteExternalException {
+ //super.writeExternal(parentNode);
+ //JDOMExternalizerUtil.writeField(parentNode, LOG_MESSAGE_OPTION_NAME, getLogMessage().toExternalForm());
+ //}
+
+ //public void setLogMessage(TextWithImports logMessage) {
+ // myLogMessage = logMessage;
+ //}
+
+ public abstract PsiElement getEvaluationElement();
+
+ protected TextWithImports getLogMessage() {
+ return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, myXBreakpoint.getLogExpression());
+ }
+
+ protected TextWithImports getCondition() {
+ return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, myXBreakpoint.getCondition());
+ }
+
+ public boolean isEnabled() {
+ return myXBreakpoint.isEnabled();
+ }
+
+ public void setEnabled(boolean enabled) {
+ myXBreakpoint.setEnabled(enabled);
+ }
+
+ protected boolean isLogEnabled() {
+ return myXBreakpoint.isLogMessage();
+ }
+
+ public void setLogEnabled(boolean logEnabled) {
+ myXBreakpoint.setLogMessage(logEnabled);
+ }
+
+ protected boolean isLogExpressionEnabled() {
+ String expression = myXBreakpoint.getLogExpression();
+ if (expression == null || expression.isEmpty()) {
+ return false;
+ }
+ return !getLogMessage().isEmpty();
+ }
+
+ @Override
+ public boolean isCountFilterEnabled() {
+ if (getProperties() == null) {
+ return false;
+ }
+ return getProperties().COUNT_FILTER_ENABLED;
+ }
+ public void setCountFilterEnabled(boolean enabled) {
+ getProperties().COUNT_FILTER_ENABLED = enabled;
+ }
+
+ @Override
+ public int getCountFilter() {
+ return getProperties().COUNT_FILTER;
+ }
+
+ public void setCountFilter(int filter) {
+ getProperties().COUNT_FILTER = filter;
+ }
+
+ @Override
+ public boolean isClassFiltersEnabled() {
+ if (getProperties() == null) {
+ return false;
+ }
+ return getProperties().CLASS_FILTERS_ENABLED;
+ }
+
+ public void setClassFiltersEnabled(boolean enabled) {
+ getProperties().CLASS_FILTERS_ENABLED = enabled;
+ }
+
+ @Override
+ public ClassFilter[] getClassFilters() {
+ return getProperties().getClassFilters();
+ }
+
+ public void setClassFilters(ClassFilter[] filters) {
+ getProperties().setClassFilters(filters);
+ }
+
+ @Override
+ public ClassFilter[] getClassExclusionFilters() {
+ return getProperties().getClassExclusionFilters();
+ }
+
+ protected void setClassExclusionFilters(ClassFilter[] filters) {
+ getProperties().setClassExclusionFilters(filters);
+ }
+
+ @Override
+ public boolean isInstanceFiltersEnabled() {
+ if (getProperties() == null) {
+ return false;
+ }
+ return getProperties().INSTANCE_FILTERS_ENABLED;
+ }
+
+ public void setInstanceFiltersEnabled(boolean enabled) {
+ getProperties().INSTANCE_FILTERS_ENABLED = enabled;
}
@Override
- public void writeExternal(Element parentNode) throws WriteExternalException {
- super.writeExternal(parentNode);
- JDOMExternalizerUtil.writeField(parentNode, LOG_MESSAGE_OPTION_NAME, getLogMessage().toExternalForm());
+ public InstanceFilter[] getInstanceFilters() {
+ return getProperties().getInstanceFilters();
+ }
+
+ public void setInstanceFilters(InstanceFilter[] filters) {
+ getProperties().setInstanceFilters(filters);
+ }
+
+ private static String getSuspendPolicy(XBreakpoint breakpoint) {
+ switch (breakpoint.getSuspendPolicy()) {
+ case ALL:
+ return DebuggerSettings.SUSPEND_ALL;
+ case THREAD:
+ return DebuggerSettings.SUSPEND_THREAD;
+ case NONE:
+ return DebuggerSettings.SUSPEND_NONE;
+
+ default:
+ throw new IllegalArgumentException("unknown suspend policy");
+ }
+ }
+
+ static SuspendPolicy transformSuspendPolicy(String policy) {
+ if (DebuggerSettings.SUSPEND_ALL.equals(policy)) {
+ return SuspendPolicy.ALL;
+ } else if (DebuggerSettings.SUSPEND_THREAD.equals(policy)) {
+ return SuspendPolicy.THREAD;
+ } else if (DebuggerSettings.SUSPEND_NONE.equals(policy)) {
+ return SuspendPolicy.NONE;
+ } else {
+ throw new IllegalArgumentException("unknown suspend policy");
+ }
}
- public TextWithImports getLogMessage() {
- return myLogMessage;
+ protected boolean isSuspend() {
+ return myXBreakpoint.getSuspendPolicy() != SuspendPolicy.NONE;
+ }
+
+ @Override
+ public String getSuspendPolicy() {
+ return getSuspendPolicy(myXBreakpoint);
+ }
+
+ public void setSuspendPolicy(String policy) {
+ myXBreakpoint.setSuspendPolicy(transformSuspendPolicy(policy));
+ }
+
+ protected void setLogMessage(@Nullable TextWithImports logMessage) {
+ if (logMessage != null && !logMessage.getText().isEmpty()) {
+ myXBreakpoint.setLogExpression(logMessage.toExternalForm());
+ }
+ else {
+ myXBreakpoint.setLogExpression(null);
+ }
+ }
+
+ protected boolean isConditionEnabled() {
+ String condition = myXBreakpoint.getCondition();
+ if (condition == null || condition.isEmpty()) {
+ return false;
+ }
+ return !getCondition().isEmpty();
+ }
+
+ public void setCondition(@Nullable TextWithImports condition) {
+ if (condition != null && !condition.getText().isEmpty()) {
+ myXBreakpoint.setCondition(condition.toExternalForm());
+ }
+ else {
+ myXBreakpoint.setCondition(null);
+ }
}
- public void setLogMessage(TextWithImports logMessage) {
- myLogMessage = logMessage;
+ protected void addInstanceFilter(long l) {
+ getProperties().addInstanceFilter(l);
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java
deleted file mode 100644
index 67c32935849e..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointFactory.java
+++ /dev/null
@@ -1,81 +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.ui.breakpoints;
-
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Key;
-import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem;
-import org.jdom.Element;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-
-/**
- * Used to deexternalize breakpoints of certain category while reading saved configuration and for creating configuration UI
- */
-public abstract class BreakpointFactory {
- public static final ExtensionPointName<BreakpointFactory> EXTENSION_POINT_NAME =
- ExtensionPointName.create("com.intellij.debugger.breakpointFactory");
-
- public static BreakpointFactory[] getBreakpointFactories() {
- return ApplicationManager.getApplication().getExtensions(EXTENSION_POINT_NAME);
- }
-
- public abstract Breakpoint createBreakpoint(Project project, final Element element);
-
- public abstract Key<? extends Breakpoint> getBreakpointCategory();
-
- public abstract Icon getIcon();
-
- public abstract Icon getDisabledIcon();
-
- @Nullable
- public static BreakpointFactory getInstance(Key<? extends Breakpoint> category) {
- final BreakpointFactory[] allFactories = getBreakpointFactories();
- for (final BreakpointFactory factory : allFactories) {
- if (category.equals(factory.getBreakpointCategory())) {
- return factory;
- }
- }
- return null;
- }
-
- protected abstract String getHelpID();
-
- public abstract String getDisplayName();
-
- @Nullable
- public abstract BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact);
-
- @Nullable
- public Breakpoint addBreakpoint(Project project) {
- return null;
- }
-
- public boolean canAddBreakpoints() {
- return false;
- }
-
- public boolean breakpointCanBeRemoved(Breakpoint breakpoint) {
- return true;
- }
-
- public BreakpointItem createBreakpointItem(final Breakpoint breakpoint) {
- return new JavaBreakpointItem(this, breakpoint);
- }
-}
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 1bcbf3e9954b..76c55c7b4ae9 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
@@ -20,14 +20,11 @@
*/
package com.intellij.debugger.ui.breakpoints;
-import com.intellij.codeInsight.folding.impl.actions.ExpandRegionAction;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.DebuggerInvocationUtil;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.BreakpointStepMethodFilter;
import com.intellij.debugger.engine.DebugProcessImpl;
-import com.intellij.debugger.engine.evaluation.CodeFragmentKind;
-import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
import com.intellij.debugger.engine.requests.RequestManagerImpl;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerContextListener;
@@ -35,41 +32,31 @@ import com.intellij.debugger.impl.DebuggerManagerImpl;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.debugger.ui.JavaDebuggerSupport;
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.editor.Editor;
-import com.intellij.openapi.editor.EditorFactory;
-import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
-import com.intellij.openapi.editor.markup.MarkupEditorFilterFactory;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.fileEditor.FileEditor;
-import com.intellij.openapi.fileEditor.FileEditorManager;
-import com.intellij.openapi.fileEditor.TextEditor;
-import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiFile;
import com.intellij.util.Alarm;
import com.intellij.util.EventDispatcher;
-import com.intellij.util.IJSwingUtilities;
-import com.intellij.util.SystemProperties;
-import com.intellij.util.containers.MultiMap;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.XDebuggerUtil;
-import com.intellij.xdebugger.breakpoints.XBreakpointType;
+import com.intellij.xdebugger.breakpoints.*;
import com.intellij.xdebugger.impl.DebuggerSupport;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
-import com.sun.jdi.Field;
+import com.intellij.xdebugger.impl.breakpoints.XBreakpointManagerImpl;
+import com.intellij.xdebugger.impl.breakpoints.XDependentBreakpointManager;
import com.sun.jdi.InternalException;
-import com.sun.jdi.ObjectReference;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.request.*;
import gnu.trove.THashMap;
@@ -78,11 +65,9 @@ import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.java.debugger.breakpoints.JavaBreakpointAdapter;
-import org.jetbrains.java.debugger.breakpoints.JavaBreakpointType;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaExceptionBreakpointProperties;
import javax.swing.*;
-import java.awt.event.MouseEvent;
import java.util.*;
public class BreakpointManager {
@@ -94,15 +79,13 @@ public class BreakpointManager {
@NonNls private static final String DEFAULT_CONDITION_STATE_ATTRIBUTE_NAME = "default_condition_enabled";
@NonNls private static final String RULES_GROUP_NAME = "breakpoint_rules";
+ private static final String CONVERTED_PARAM = "converted";
private final Project myProject;
- private AnyExceptionBreakpoint myAnyExceptionBreakpoint;
- private final List<Breakpoint> myBreakpoints = new ArrayList<Breakpoint>(); // breakpoints storage, access should be synchronized
- private final List<EnableBreakpointRule> myBreakpointRules = new ArrayList<EnableBreakpointRule>(); // breakpoint rules
+ private final Map<XBreakpoint, Breakpoint> myBreakpoints = new HashMap<XBreakpoint, Breakpoint>(); // breakpoints storage, access should be synchronized
@Nullable private List<Breakpoint> myBreakpointsListForIteration = null; // another list for breakpoints iteration, unsynchronized access ok
- private final MultiMap<Document, BreakpointWithHighlighter> myDocumentBreakpoints = MultiMap.createSmartList();
private final Map<String, String> myUIProperties = new LinkedHashMap<String, String>();
- private final Map<Key<? extends Breakpoint>, BreakpointDefaults> myBreakpointDefaults = new LinkedHashMap<Key<? extends Breakpoint>, BreakpointDefaults>();
+ //private final Map<Key<? extends Breakpoint>, BreakpointDefaults> myBreakpointDefaults = new LinkedHashMap<Key<? extends Breakpoint>, BreakpointDefaults>();
private final EventDispatcher<BreakpointManagerListener> myDispatcher = EventDispatcher.create(BreakpointManagerListener.class);
@@ -155,212 +138,35 @@ public class BreakpointManager {
}
}
});
-
- if (!project.isDefault()) {
- XDebuggerManager.getInstance(project).getBreakpointManager().addBreakpointListener(
- XBreakpointType.EXTENSION_POINT_NAME.findExtension(JavaBreakpointType.class), new JavaBreakpointAdapter(project), project);
- }
}
public void init() {
- EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster();
- eventMulticaster.addEditorMouseListener(new EditorMouseAdapter() {
- @Nullable private EditorMouseEvent myMousePressedEvent;
-
- @Nullable
- private Breakpoint toggleBreakpoint(final boolean mostSuitingBreakpoint, final int line, boolean temporary) {
- final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
- if (editor == null) {
- return null;
- }
- final Document document = editor.getDocument();
- final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
- if (!JavaBreakpointType.doCanPutAt(psiFile)) {
- return null;
- }
-
- if (SystemProperties.getBooleanProperty("java.debugger.xBreakpoint", false) &&
- XBreakpointType.EXTENSION_POINT_NAME.findExtension(JavaBreakpointType.class)
- .canPutAt(psiFile.getVirtualFile(), line, myProject)) {
- return null;
- }
-
- PsiDocumentManager.getInstance(myProject).commitDocument(document);
-
- int offset = editor.getCaretModel().getOffset();
- int editorLine = editor.getDocument().getLineNumber(offset);
- if (editorLine != line) {
- if (line < 0 || line >= document.getLineCount()) {
- return null;
- }
- offset = editor.getDocument().getLineStartOffset(line);
- }
-
- ExpandRegionAction.expandRegionAtOffset(myProject, editor, offset);
-
- Breakpoint breakpoint = findBreakpoint(document, offset, null);
- if (breakpoint == null) {
- boolean isInsideCompiledClass = StdFileTypes.CLASS.equals(psiFile.getFileType());
- if (mostSuitingBreakpoint || isInsideCompiledClass) {
- breakpoint = addFieldBreakpoint(document, offset);
- if (breakpoint == null) {
- breakpoint = addMethodBreakpoint(document, line);
- }
- if (breakpoint == null && !isInsideCompiledClass) {
- breakpoint = addLineBreakpoint(document, line);
- }
- }
- else {
- breakpoint = addLineBreakpoint(document, line);
-
- if (breakpoint == null) {
- breakpoint = addMethodBreakpoint(document, line);
- }
- }
-
- if (breakpoint != null) {
- breakpoint.REMOVE_AFTER_HIT = temporary;
- RequestManagerImpl.createRequests(breakpoint);
- }
- return breakpoint;
- }
- else {
- removeBreakpoint(breakpoint);
- return null;
- }
- }
-
- private boolean isFromMyProject(Editor editor) {
- FileEditor[] allEditors = FileEditorManager.getInstance(myProject).getAllEditors();
- for (FileEditor ed : allEditors) {
- if (!(ed instanceof TextEditor)) {
- continue;
- }
- if (((TextEditor)ed).getEditor().equals(editor)) {
- return true;
- }
- }
- return false;
- }
-
- //mousePressed + mouseReleased is a hack to keep selection in editor when shift is pressed
+ XBreakpointManager manager = XDebuggerManager.getInstance(myProject).getBreakpointManager();
+ manager.addBreakpointListener(new XBreakpointListener() {
@Override
- public void mousePressed(@NotNull EditorMouseEvent e) {
- if (MarkupEditorFilterFactory.createIsDiffFilter().avaliableIn(e.getEditor())) return;
-
- if (e.isConsumed()) return;
-
- if (e.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA && e.getMouseEvent().isShiftDown()) {
- myMousePressedEvent = e;
- e.consume();
+ public void breakpointAdded(@NotNull XBreakpoint xBreakpoint) {
+ if (isJavaType(xBreakpoint)) {
+ onBreakpointAdded(xBreakpoint);
}
}
@Override
- public void mouseReleased(@NotNull EditorMouseEvent e) {
- if (myMousePressedEvent != null) {
- mouseClicked(e);
- }
- myMousePressedEvent = null;
+ public void breakpointRemoved(@NotNull XBreakpoint xBreakpoint) {
+ onBreakpointRemoved(xBreakpoint);
}
@Override
- public void mouseClicked(@NotNull final EditorMouseEvent e) {
- if (MarkupEditorFilterFactory.createIsDiffFilter().avaliableIn(e.getEditor())) return;
-
- if (e.isConsumed()) return;
-
- if (e.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA) {
- PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Runnable() {
- @Override
- public void run() {
- final Editor editor = e.getEditor();
- if (!isFromMyProject(editor)) {
- return;
- }
- final int line = editor.xyToLogicalPosition(e.getMouseEvent().getPoint()).line;
- final Document document = editor.getDocument();
- if (line < 0 || line >= document.getLineCount()) {
- return;
- }
- MouseEvent event = e.getMouseEvent();
- if (event.isPopupTrigger()) {
- return;
- }
- if (event.getButton() != 1) {
- return;
- }
- if (e.getMouseEvent().isControlDown() || e.getMouseEvent().isMetaDown()) {
- return;
- }
-
- VirtualFile file = FileDocumentManager.getInstance().getFile(document);
- if (file != null && XDebuggerUtil.getInstance().canPutBreakpointAt(myProject, file, line)) {
- return;
- }
- e.consume();
-
- DebuggerInvocationUtil.invokeLater(myProject, new Runnable() {
- @Override
- public void run() {
- final boolean suitingBreakpoint = e.getMouseEvent().isAltDown() && !e.getMouseEvent().isShiftDown();
- final boolean temporary = e.getMouseEvent().isAltDown() && e.getMouseEvent().isShiftDown();
-
- final Breakpoint breakpoint = toggleBreakpoint(suitingBreakpoint, line, temporary);
-
-
- if (!e.getMouseEvent().isAltDown() && e.getMouseEvent().isShiftDown() && breakpoint != null) {
- breakpoint.LOG_EXPRESSION_ENABLED = true;
- String selection = editor.getSelectionModel().getSelectedText();
- String text = selection != null ? selection : DebuggerBundle.message("breakpoint.log.message",
- breakpoint.getDisplayName());
- breakpoint.setLogMessage(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, text));
- breakpoint.SUSPEND = false;
- editBreakpoint(breakpoint, editor);
-
-
- //DialogWrapper dialog = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager()
- // .createConfigurationDialog(breakpoint, BreakpointPropertiesPanel.CONTROL_LOG_MESSAGE);
- //dialog.show();
- //
- //if (!dialog.isOK()) {
- // removeBreakpoint(breakpoint);
- //}
- }
- }
- });
- }
- });
+ public void breakpointChanged(@NotNull XBreakpoint xBreakpoint) {
+ Breakpoint breakpoint = myBreakpoints.get(xBreakpoint);
+ if (breakpoint != null) {
+ fireBreakpointChanged(breakpoint);
}
}
- }, myProject);
-
- eventMulticaster.addDocumentListener(new DocumentAdapter() {
- private final Alarm myUpdateAlarm = new Alarm();
+ });
+ }
- @Override
- public void documentChanged(@NotNull final DocumentEvent e) {
- final Document document = e.getDocument();
- //noinspection SynchronizeOnThis
- synchronized (BreakpointManager.this) {
- Collection<BreakpointWithHighlighter> breakpoints = myDocumentBreakpoints.get(document);
- if (!breakpoints.isEmpty()) {
- myUpdateAlarm.cancelAllRequests();
- // must create new array in order to avoid "concurrent modification" errors
- final List<BreakpointWithHighlighter> breakpointsToUpdate = new ArrayList<BreakpointWithHighlighter>(breakpoints);
- myUpdateAlarm.addRequest(new Runnable() {
- @Override
- public void run() {
- if (!myProject.isDisposed()) {
- PsiDocumentManager.getInstance(myProject).commitDocument(document);
- update(breakpointsToUpdate);
- }
- }
- }, 300, ModalityState.NON_MODAL);
- }
- }
- }
- }, myProject);
+ private XBreakpointManager getXBreakpointManager() {
+ return XDebuggerManager.getInstance(myProject).getBreakpointManager();
}
public void editBreakpoint(final Breakpoint breakpoint, final Editor editor) {
@@ -380,17 +186,34 @@ public class BreakpointManager {
});
}
- @NotNull
- public BreakpointDefaults getBreakpointDefaults(Key<? extends Breakpoint> category) {
- BreakpointDefaults defaults = myBreakpointDefaults.get(category);
- if (defaults == null) {
- defaults = new BreakpointDefaults();
- }
- return defaults;
- }
+ //@NotNull
+ //public BreakpointDefaults getBreakpointDefaults(Key<? extends Breakpoint> category) {
+ // BreakpointDefaults defaults = myBreakpointDefaults.get(category);
+ // if (defaults == null) {
+ // defaults = new BreakpointDefaults();
+ // }
+ // return defaults;
+ //}
public void setBreakpointDefaults(Key<? extends Breakpoint> category, BreakpointDefaults defaults) {
- myBreakpointDefaults.put(category, defaults);
+ Class typeCls = null;
+ if (LineBreakpoint.CATEGORY.toString().equals(category.toString())) {
+ typeCls = JavaLineBreakpointType.class;
+ }
+ else if (MethodBreakpoint.CATEGORY.toString().equals(category.toString())) {
+ typeCls = JavaMethodBreakpointType.class;
+ }
+ else if (FieldBreakpoint.CATEGORY.toString().equals(category.toString())) {
+ typeCls = JavaFieldBreakpointType.class;
+ }
+ else if (ExceptionBreakpoint.CATEGORY.toString().equals(category.toString())) {
+ typeCls = JavaExceptionBreakpointType.class;
+ }
+ if (typeCls != null) {
+ XBreakpointType<XBreakpoint<?>, ?> type = XDebuggerUtil.getInstance().findBreakpointType(typeCls);
+ ((XBreakpointManagerImpl)getXBreakpointManager()).getBreakpointDefaults(type).setSuspendPolicy(Breakpoint.transformSuspendPolicy(defaults.getSuspendPolicy()));
+ }
+ //myBreakpointDefaults.put(category, defaults);
}
@@ -410,8 +233,8 @@ public class BreakpointManager {
if (!LineBreakpoint.canAddLineBreakpoint(myProject, document, lineIndex)) {
return null;
}
-
- LineBreakpoint breakpoint = LineBreakpoint.create(myProject, document, lineIndex);
+ XLineBreakpoint xLineBreakpoint = addXLineBreakpoint(JavaLineBreakpointType.class, document, lineIndex);
+ LineBreakpoint breakpoint = LineBreakpoint.create(myProject, xLineBreakpoint);
if (breakpoint == null) {
return null;
}
@@ -420,15 +243,15 @@ public class BreakpointManager {
return breakpoint;
}
- @Nullable
- public FieldBreakpoint addFieldBreakpoint(Field field, ObjectReference object) {
- ApplicationManager.getApplication().assertIsDispatchThread();
- final FieldBreakpoint fieldBreakpoint = FieldBreakpoint.create(myProject, field, object);
- if (fieldBreakpoint != null) {
- addBreakpoint(fieldBreakpoint);
- }
- return fieldBreakpoint;
- }
+ //@Nullable
+ //public FieldBreakpoint addFieldBreakpoint(Field field, ObjectReference object) {
+ // ApplicationManager.getApplication().assertIsDispatchThread();
+ // final FieldBreakpoint fieldBreakpoint = FieldBreakpoint.create(myProject, field, object, null);
+ // if (fieldBreakpoint != null) {
+ // addBreakpoint(fieldBreakpoint);
+ // }
+ // return fieldBreakpoint;
+ //}
@Nullable
public FieldBreakpoint addFieldBreakpoint(@NotNull Document document, int offset) {
@@ -449,7 +272,8 @@ public class BreakpointManager {
@Nullable
public FieldBreakpoint addFieldBreakpoint(Document document, int lineIndex, String fieldName) {
ApplicationManager.getApplication().assertIsDispatchThread();
- FieldBreakpoint fieldBreakpoint = FieldBreakpoint.create(myProject, document, lineIndex, fieldName);
+ XLineBreakpoint xBreakpoint = addXLineBreakpoint(JavaFieldBreakpointType.class, document, lineIndex);
+ FieldBreakpoint fieldBreakpoint = FieldBreakpoint.create(myProject, fieldName, xBreakpoint);
if (fieldBreakpoint != null) {
addBreakpoint(fieldBreakpoint);
}
@@ -457,21 +281,30 @@ public class BreakpointManager {
}
@NotNull
- public ExceptionBreakpoint addExceptionBreakpoint(@NotNull String exceptionClassName, String packageName) {
+ public ExceptionBreakpoint addExceptionBreakpoint(@NotNull final String exceptionClassName, final String packageName) {
ApplicationManager.getApplication().assertIsDispatchThread();
- ExceptionBreakpoint breakpoint = new ExceptionBreakpoint(myProject, exceptionClassName, packageName);
- addBreakpoint(breakpoint);
- if (LOG.isDebugEnabled()) {
- LOG.debug("ExceptionBreakpoint Added");
- }
- return breakpoint;
+ final JavaExceptionBreakpointType type = (JavaExceptionBreakpointType)XDebuggerUtil.getInstance().findBreakpointType(JavaExceptionBreakpointType.class);
+ return ApplicationManager.getApplication().runWriteAction(new Computable<ExceptionBreakpoint>() {
+ @Override
+ public ExceptionBreakpoint compute() {
+ XBreakpoint<JavaExceptionBreakpointProperties> xBreakpoint = XDebuggerManager.getInstance(myProject).getBreakpointManager()
+ .addBreakpoint(type, new JavaExceptionBreakpointProperties(exceptionClassName, packageName));
+ ExceptionBreakpoint breakpoint = new ExceptionBreakpoint(myProject, exceptionClassName, packageName, xBreakpoint);
+ addBreakpoint(breakpoint);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("ExceptionBreakpoint Added");
+ }
+ return breakpoint;
+ }
+ });
}
@Nullable
public MethodBreakpoint addMethodBreakpoint(Document document, int lineIndex) {
ApplicationManager.getApplication().assertIsDispatchThread();
- MethodBreakpoint breakpoint = MethodBreakpoint.create(myProject, document, lineIndex);
+ XLineBreakpoint xBreakpoint = addXLineBreakpoint(JavaMethodBreakpointType.class, document, lineIndex);
+ MethodBreakpoint breakpoint = MethodBreakpoint.create(myProject, xBreakpoint);
if (breakpoint == null) {
return null;
}
@@ -482,10 +315,23 @@ public class BreakpointManager {
return breakpoint;
}
+ private <B extends XBreakpoint<?>> XLineBreakpoint addXLineBreakpoint(Class<? extends XBreakpointType<B,?>> typeCls, Document document, final int lineIndex) {
+ final XBreakpointType<B, ?> type = XDebuggerUtil.getInstance().findBreakpointType(typeCls);
+ final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
+ return ApplicationManager.getApplication().runWriteAction(new Computable<XLineBreakpoint>() {
+ @Override
+ public XLineBreakpoint compute() {
+ return XDebuggerManager.getInstance(myProject).getBreakpointManager()
+ .addLineBreakpoint((XLineBreakpointType)type, file.getUrl(), lineIndex,
+ ((XLineBreakpointType)type).createBreakpointProperties(file, lineIndex));
+ }
+ });
+ }
+
@Nullable
public WildcardMethodBreakpoint addMethodBreakpoint(String classPattern, String methodName) {
ApplicationManager.getApplication().assertIsDispatchThread();
- WildcardMethodBreakpoint breakpoint = WildcardMethodBreakpoint.create(myProject, classPattern, methodName);
+ WildcardMethodBreakpoint breakpoint = WildcardMethodBreakpoint.create(myProject, classPattern, methodName, null);
if (breakpoint == null) {
return null;
}
@@ -531,14 +377,6 @@ public class BreakpointManager {
*/
@Nullable
public <T extends BreakpointWithHighlighter> T findBreakpoint(final Document document, final int offset, @Nullable final Key<T> category) {
- for (BreakpointWithHighlighter breakpointWithHighlighter : myDocumentBreakpoints.get(document)) {
- if (breakpointWithHighlighter.isAt(document, offset) &&
- (category == null || category.equals(breakpointWithHighlighter.getCategory()))) {
- //noinspection unchecked
- return (T)breakpointWithHighlighter;
- }
- }
-
for (final Breakpoint breakpoint : getBreakpoints()) {
if (breakpoint instanceof BreakpointWithHighlighter && ((BreakpointWithHighlighter)breakpoint).isAt(document, offset)) {
if (category == null || category.equals(breakpoint.getCategory())) {
@@ -550,7 +388,17 @@ public class BreakpointManager {
return null;
}
+ public Breakpoint findBreakpoint(XBreakpoint xBreakpoint) {
+ return myBreakpoints.get(xBreakpoint);
+ }
+
+ private List<Element> myOriginalBreakpointsNodes = new ArrayList<Element>();
+
public void readExternal(@NotNull final Element parentNode) {
+ // save old breakpoints
+ for (Element element : parentNode.getChildren()) {
+ myOriginalBreakpointsNodes.add(element.clone());
+ }
if (myProject.isOpen()) {
doRead(parentNode);
}
@@ -577,6 +425,10 @@ public class BreakpointManager {
if (group.getName().equals(RULES_GROUP_NAME)) {
continue;
}
+ // skip already converted
+ if (group.getAttribute(CONVERTED_PARAM) != null) {
+ continue;
+ }
final String categoryName = group.getName();
final Key<Breakpoint> breakpointCategory = BreakpointCategory.lookup(categoryName);
final String defaultPolicy = group.getAttributeValue(DEFAULT_SUSPEND_POLICY_ATTRIBUTE_NAME);
@@ -586,16 +438,15 @@ public class BreakpointManager {
if (!AnyExceptionBreakpoint.ANY_EXCEPTION_BREAKPOINT.equals(breakpointCategory)) {
// for compatibility with previous format
anyExceptionBreakpointGroup = group.getChild(AnyExceptionBreakpoint.ANY_EXCEPTION_BREAKPOINT.toString());
- final BreakpointFactory factory = BreakpointFactory.getInstance(breakpointCategory);
- if (factory != null) {
- for (final Object o : group.getChildren("breakpoint")) {
- Element breakpointNode = (Element)o;
- Breakpoint breakpoint = factory.createBreakpoint(myProject, breakpointNode);
+ //final BreakpointFactory factory = BreakpointFactory.getInstance(breakpointCategory);
+ //if (factory != null) {
+ for (Element breakpointNode : group.getChildren("breakpoint")) {
+ //Breakpoint breakpoint = factory.createBreakpoint(myProject, breakpointNode);
+ Breakpoint breakpoint = createBreakpoint(categoryName, breakpointNode);
breakpoint.readExternal(breakpointNode);
- addBreakpoint(breakpoint);
nameToBreakpointMap.put(breakpoint.getDisplayName(), breakpoint);
}
- }
+ //}
}
else {
anyExceptionBreakpointGroup = group;
@@ -604,10 +455,14 @@ public class BreakpointManager {
if (anyExceptionBreakpointGroup != null) {
final Element breakpointElement = group.getChild("breakpoint");
if (breakpointElement != null) {
- getAnyExceptionBreakpoint().readExternal(breakpointElement);
+ XBreakpointManager manager = XDebuggerManager.getInstance(myProject).getBreakpointManager();
+ JavaExceptionBreakpointType type = (JavaExceptionBreakpointType)XDebuggerUtil.getInstance().findBreakpointType(JavaExceptionBreakpointType.class);
+ XBreakpoint<JavaExceptionBreakpointProperties> xBreakpoint = manager.getDefaultBreakpoint(type);
+ Breakpoint breakpoint = createJavaBreakpoint(xBreakpoint);
+ breakpoint.readExternal(breakpointElement);
+ addBreakpoint(breakpoint);
}
}
-
}
}
catch (InvalidDataException ignored) {
@@ -615,9 +470,12 @@ public class BreakpointManager {
final Element rulesGroup = parentNode.getChild(RULES_GROUP_NAME);
if (rulesGroup != null) {
- final List rules = rulesGroup.getChildren("rule");
- for (final Object rule1 : rules) {
- final Element rule = (Element)rule1;
+ final List<Element> rules = rulesGroup.getChildren("rule");
+ for (Element rule : rules) {
+ // skip already converted
+ if (rule.getAttribute(CONVERTED_PARAM) != null) {
+ continue;
+ }
final Element master = rule.getChild(MASTER_BREAKPOINT_TAGNAME);
if (master == null) {
continue;
@@ -634,7 +492,11 @@ public class BreakpointManager {
if (slaveBreakpoint == null) {
continue;
}
- addBreakpointRule(new EnableBreakpointRule(BreakpointManager.this, masterBreakpoint, slaveBreakpoint, "true".equalsIgnoreCase(rule.getAttributeValue("leaveEnabled"))));
+
+ boolean leaveEnabled = "true".equalsIgnoreCase(rule.getAttributeValue("leaveEnabled"));
+ XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager();
+ dependentBreakpointManager.setMasterBreakpoint(slaveBreakpoint.myXBreakpoint, masterBreakpoint.myXBreakpoint, leaveEnabled);
+ //addBreakpointRule(new EnableBreakpointRule(BreakpointManager.this, masterBreakpoint, slaveBreakpoint, leaveEnabled));
}
}
@@ -662,112 +524,190 @@ public class BreakpointManager {
}
}
+ private Breakpoint createBreakpoint(String category, Element breakpointNode) throws InvalidDataException {
+ XBreakpoint xBreakpoint = null;
+ if (category.equals(LineBreakpoint.CATEGORY.toString())) {
+ xBreakpoint = createXLineBreakpoint(JavaLineBreakpointType.class, breakpointNode);
+ }
+ else if (category.equals(MethodBreakpoint.CATEGORY.toString())) {
+ if (breakpointNode.getAttribute("url") != null) {
+ xBreakpoint = createXLineBreakpoint(JavaMethodBreakpointType.class, breakpointNode);
+ }
+ else {
+ xBreakpoint = createXBreakpoint(JavaWildcardMethodBreakpointType.class, breakpointNode);
+ }
+ }
+ else if (category.equals(FieldBreakpoint.CATEGORY.toString())) {
+ xBreakpoint = createXLineBreakpoint(JavaFieldBreakpointType.class, breakpointNode);
+ }
+ else if (category.equals(ExceptionBreakpoint.CATEGORY.toString())) {
+ xBreakpoint = createXBreakpoint(JavaExceptionBreakpointType.class, breakpointNode);
+ }
+ if (xBreakpoint == null) {
+ throw new IllegalStateException("Unknown breakpoint category " + category);
+ }
+ return myBreakpoints.get(xBreakpoint);
+ }
+
+ private <B extends XBreakpoint<?>> XBreakpoint createXBreakpoint(Class<? extends XBreakpointType<B, ?>> typeCls,
+ Element breakpointNode) throws InvalidDataException {
+ final XBreakpointType<B, ?> type = XDebuggerUtil.getInstance().findBreakpointType(typeCls);
+ return ApplicationManager.getApplication().runWriteAction(new Computable<XBreakpoint>() {
+ @Override
+ public XBreakpoint compute() {
+ return XDebuggerManager.getInstance(myProject).getBreakpointManager()
+ .addBreakpoint((XBreakpointType)type, type.createProperties());
+ }});
+ }
+
+ private <B extends XBreakpoint<?>> XLineBreakpoint createXLineBreakpoint(Class<? extends XBreakpointType<B, ?>> typeCls,
+ Element breakpointNode) throws InvalidDataException {
+ final String url = breakpointNode.getAttributeValue("url");
+ VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(url);
+ if (vFile == null) {
+ throw new InvalidDataException(DebuggerBundle.message("error.breakpoint.file.not.found", url));
+ }
+ final Document doc = FileDocumentManager.getInstance().getDocument(vFile);
+ if (doc == null) {
+ throw new InvalidDataException(DebuggerBundle.message("error.cannot.load.breakpoint.file", url));
+ }
+
+ final int line;
+ try {
+ //noinspection HardCodedStringLiteral
+ line = Integer.parseInt(breakpointNode.getAttributeValue("line"));
+ }
+ catch (Exception e) {
+ throw new InvalidDataException("Line number is invalid for breakpoint");
+ }
+ return addXLineBreakpoint(typeCls, doc, line);
+ }
+
//used in Fabrique
public synchronized void addBreakpoint(Breakpoint breakpoint) {
- myBreakpoints.add(breakpoint);
+ myBreakpoints.put(breakpoint.myXBreakpoint, breakpoint);
myBreakpointsListForIteration = null;
- if (breakpoint instanceof BreakpointWithHighlighter) {
- BreakpointWithHighlighter breakpointWithHighlighter = (BreakpointWithHighlighter)breakpoint;
- final Document document = breakpointWithHighlighter.getDocument();
- if (document != null) {
- myDocumentBreakpoints.putValue(document, breakpointWithHighlighter);
- }
- }
+ breakpoint.updateUI();
+ RequestManagerImpl.createRequests(breakpoint);
myDispatcher.getMulticaster().breakpointsChanged();
+ if (breakpoint instanceof MethodBreakpoint || breakpoint instanceof WildcardMethodBreakpoint) {
+ XDebugSessionImpl.NOTIFICATION_GROUP.createNotification("Method breakpoints may dramatically slow down debugging", MessageType.WARNING).notify(myProject);
+ }
}
- public synchronized void removeBreakpoint(@Nullable final Breakpoint breakpoint) {
- ApplicationManager.getApplication().assertIsDispatchThread();
+ private synchronized void onBreakpointAdded(XBreakpoint xBreakpoint) {
+ Breakpoint breakpoint = createJavaBreakpoint(xBreakpoint);
+ addBreakpoint(breakpoint);
+ }
+
+ public void removeBreakpoint(@Nullable final Breakpoint breakpoint) {
if (breakpoint == null) {
return;
}
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ getXBreakpointManager().removeBreakpoint(breakpoint.myXBreakpoint);
+ }
+ });
+ }
+
+ private synchronized void onBreakpointRemoved(@Nullable final XBreakpoint xBreakpoint) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ if (xBreakpoint == null) {
+ return;
+ }
- if (myBreakpoints.remove(breakpoint)) {
- updateBreakpointRules(breakpoint);
+ Breakpoint breakpoint = myBreakpoints.remove(xBreakpoint);
+ if (breakpoint != null) {
+ //updateBreakpointRules(breakpoint);
myBreakpointsListForIteration = null;
- if (breakpoint instanceof BreakpointWithHighlighter) {
- for (Document document : myDocumentBreakpoints.keySet()) {
- if (myDocumentBreakpoints.remove(document, (BreakpointWithHighlighter)breakpoint)) {
- break;
- }
- }
- }
//we delete breakpoints inside release, so gutter will not fire events to deleted breakpoints
breakpoint.delete();
+ RequestManagerImpl.deleteRequests(breakpoint);
myDispatcher.getMulticaster().breakpointsChanged();
}
}
public void writeExternal(@NotNull final Element parentNode) {
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- @Override
- public void run() {
- removeInvalidBreakpoints();
- final Map<Key<? extends Breakpoint>, Element> categoryToElementMap = new THashMap<Key<? extends Breakpoint>, Element>();
- for (Key<? extends Breakpoint> category : myBreakpointDefaults.keySet()) {
- final Element group = getCategoryGroupElement(categoryToElementMap, category, parentNode);
- final BreakpointDefaults defaults = getBreakpointDefaults(category);
- group.setAttribute(DEFAULT_SUSPEND_POLICY_ATTRIBUTE_NAME, String.valueOf(defaults.getSuspendPolicy()));
- group.setAttribute(DEFAULT_CONDITION_STATE_ATTRIBUTE_NAME, String.valueOf(defaults.isConditionEnabled()));
- }
- // don't store invisible breakpoints
- for (Breakpoint breakpoint : getBreakpoints()) {
- if (breakpoint.isValid() &&
- (!(breakpoint instanceof BreakpointWithHighlighter) || ((BreakpointWithHighlighter)breakpoint).isVisible())) {
- writeBreakpoint(getCategoryGroupElement(categoryToElementMap, breakpoint.getCategory(), parentNode), breakpoint);
- }
- }
- final AnyExceptionBreakpoint anyExceptionBreakpoint = getAnyExceptionBreakpoint();
- final Element group = getCategoryGroupElement(categoryToElementMap, anyExceptionBreakpoint.getCategory(), parentNode);
- writeBreakpoint(group, anyExceptionBreakpoint);
-
- final Element rules = new Element(RULES_GROUP_NAME);
- parentNode.addContent(rules);
- for (EnableBreakpointRule myBreakpointRule : myBreakpointRules) {
- writeRule(myBreakpointRule, rules);
- }
+ // restore old breakpoints
+ for (Element group : myOriginalBreakpointsNodes) {
+ if (group.getAttribute(CONVERTED_PARAM) == null) {
+ group.setAttribute(CONVERTED_PARAM, "true");
}
- });
-
- final Element uiProperties = new Element("ui_properties");
- parentNode.addContent(uiProperties);
- for (final String name : myUIProperties.keySet()) {
- Element property = new Element("property");
- uiProperties.addContent(property);
- property.setAttribute("name", name);
- property.setAttribute("value", myUIProperties.get(name));
- }
- }
-
- @SuppressWarnings({"HardCodedStringLiteral"})
- private static void writeRule(@NotNull final EnableBreakpointRule enableBreakpointRule, @NotNull Element element) {
- Element rule = new Element("rule");
- if (enableBreakpointRule.isLeaveEnabled()) {
- rule.setAttribute("leaveEnabled", Boolean.toString(true));
+ group.detach();
}
- element.addContent(rule);
- writeRuleBreakpoint(rule, MASTER_BREAKPOINT_TAGNAME, enableBreakpointRule.getMasterBreakpoint());
- writeRuleBreakpoint(rule, SLAVE_BREAKPOINT_TAGNAME, enableBreakpointRule.getSlaveBreakpoint());
- }
- @SuppressWarnings({"HardCodedStringLiteral"}) private static void writeRuleBreakpoint(@NotNull final Element element, final String tagName, @NotNull final Breakpoint breakpoint) {
- Element master = new Element(tagName);
- element.addContent(master);
- master.setAttribute("name", breakpoint.getDisplayName());
+ parentNode.addContent(myOriginalBreakpointsNodes);
+ //ApplicationManager.getApplication().runReadAction(new Runnable() {
+ // @Override
+ // public void run() {
+ // removeInvalidBreakpoints();
+ // final Map<Key<? extends Breakpoint>, Element> categoryToElementMap = new THashMap<Key<? extends Breakpoint>, Element>();
+ // for (Key<? extends Breakpoint> category : myBreakpointDefaults.keySet()) {
+ // final Element group = getCategoryGroupElement(categoryToElementMap, category, parentNode);
+ // final BreakpointDefaults defaults = getBreakpointDefaults(category);
+ // group.setAttribute(DEFAULT_SUSPEND_POLICY_ATTRIBUTE_NAME, String.valueOf(defaults.getSuspendPolicy()));
+ // group.setAttribute(DEFAULT_CONDITION_STATE_ATTRIBUTE_NAME, String.valueOf(defaults.isConditionEnabled()));
+ // }
+ // // don't store invisible breakpoints
+ // for (Breakpoint breakpoint : getBreakpoints()) {
+ // if (breakpoint.isValid() &&
+ // (!(breakpoint instanceof BreakpointWithHighlighter) || ((BreakpointWithHighlighter)breakpoint).isVisible())) {
+ // writeBreakpoint(getCategoryGroupElement(categoryToElementMap, breakpoint.getCategory(), parentNode), breakpoint);
+ // }
+ // }
+ // final AnyExceptionBreakpoint anyExceptionBreakpoint = getAnyExceptionBreakpoint();
+ // final Element group = getCategoryGroupElement(categoryToElementMap, anyExceptionBreakpoint.getCategory(), parentNode);
+ // writeBreakpoint(group, anyExceptionBreakpoint);
+ //
+ // final Element rules = new Element(RULES_GROUP_NAME);
+ // parentNode.addContent(rules);
+ // //for (EnableBreakpointRule myBreakpointRule : myBreakpointRules) {
+ // // writeRule(myBreakpointRule, rules);
+ // //}
+ // }
+ //});
+ //
+ //final Element uiProperties = new Element("ui_properties");
+ //parentNode.addContent(uiProperties);
+ //for (final String name : myUIProperties.keySet()) {
+ // Element property = new Element("property");
+ // uiProperties.addContent(property);
+ // property.setAttribute("name", name);
+ // property.setAttribute("value", myUIProperties.get(name));
+ //}
}
- @SuppressWarnings({"HardCodedStringLiteral"})
- private static void writeBreakpoint(@NotNull final Element group, @NotNull final Breakpoint breakpoint) {
- Element breakpointNode = new Element("breakpoint");
- group.addContent(breakpointNode);
- try {
- breakpoint.writeExternal(breakpointNode);
- }
- catch (WriteExternalException e) {
- LOG.error(e);
- }
- }
+ //@SuppressWarnings({"HardCodedStringLiteral"})
+ //private static void writeRule(@NotNull final EnableBreakpointRule enableBreakpointRule, @NotNull Element element) {
+ // Element rule = new Element("rule");
+ // if (enableBreakpointRule.isLeaveEnabled()) {
+ // rule.setAttribute("leaveEnabled", Boolean.toString(true));
+ // }
+ // element.addContent(rule);
+ // writeRuleBreakpoint(rule, MASTER_BREAKPOINT_TAGNAME, enableBreakpointRule.getMasterBreakpoint());
+ // writeRuleBreakpoint(rule, SLAVE_BREAKPOINT_TAGNAME, enableBreakpointRule.getSlaveBreakpoint());
+ //}
+
+ //@SuppressWarnings({"HardCodedStringLiteral"}) private static void writeRuleBreakpoint(@NotNull final Element element, final String tagName, @NotNull final Breakpoint breakpoint) {
+ // Element master = new Element(tagName);
+ // element.addContent(master);
+ // master.setAttribute("name", breakpoint.getDisplayName());
+ //}
+
+ //@SuppressWarnings({"HardCodedStringLiteral"})
+ //private static void writeBreakpoint(@NotNull final Element group, @NotNull final Breakpoint breakpoint) {
+ // Element breakpointNode = new Element("breakpoint");
+ // group.addContent(breakpointNode);
+ // try {
+ // breakpoint.writeExternal(breakpointNode);
+ // }
+ // catch (WriteExternalException e) {
+ // LOG.error(e);
+ // }
+ //}
private static <T extends Breakpoint> Element getCategoryGroupElement(@NotNull final Map<Key<? extends Breakpoint>, Element> categoryToElementMap, @NotNull final Key<T> category, @NotNull final Element parentNode) {
Element group = categoryToElementMap.get(category);
@@ -814,18 +754,37 @@ public class BreakpointManager {
@NotNull
public synchronized List<Breakpoint> getBreakpoints() {
if (myBreakpointsListForIteration == null) {
- myBreakpointsListForIteration = new ArrayList<Breakpoint>(myBreakpoints.size() + 1);
- myBreakpointsListForIteration.addAll(myBreakpoints);
- myBreakpointsListForIteration.add(getAnyExceptionBreakpoint());
+ myBreakpointsListForIteration = new ArrayList<Breakpoint>(myBreakpoints.size());
+
+ XBreakpoint<?>[] xBreakpoints = ApplicationManager.getApplication().runReadAction(new Computable<XBreakpoint<?>[]>() {
+ public XBreakpoint<?>[] compute() {
+ return getXBreakpointManager().getAllBreakpoints();
+ }
+ });
+ for (XBreakpoint<?> xBreakpoint : xBreakpoints) {
+ if (isJavaType(xBreakpoint)) {
+ Breakpoint breakpoint = myBreakpoints.get(xBreakpoint);
+ if (breakpoint == null) {
+ breakpoint = createJavaBreakpoint(xBreakpoint);
+ myBreakpoints.put(xBreakpoint, breakpoint);
+ }
+ }
+ }
+
+ myBreakpointsListForIteration.addAll(myBreakpoints.values());
}
return myBreakpointsListForIteration;
}
- public AnyExceptionBreakpoint getAnyExceptionBreakpoint() {
- if (myAnyExceptionBreakpoint == null) {
- myAnyExceptionBreakpoint = new AnyExceptionBreakpoint(myProject);
+ private boolean isJavaType(XBreakpoint xBreakpoint) {
+ return xBreakpoint.getType() instanceof JavaBreakpointType;
+ }
+
+ private Breakpoint createJavaBreakpoint(XBreakpoint xBreakpoint) {
+ if (xBreakpoint.getType() instanceof JavaBreakpointType) {
+ return ((JavaBreakpointType)xBreakpoint.getType()).createJavaBreakpoint(myProject, xBreakpoint);
}
- return myAnyExceptionBreakpoint;
+ throw new IllegalStateException("Unsupported breakpoint type:" + xBreakpoint.getType());
}
//interaction with RequestManagerImpl
@@ -963,6 +922,8 @@ public class BreakpointManager {
private boolean myAllowMulticasting = true;
private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
public void fireBreakpointChanged(Breakpoint breakpoint) {
+ breakpoint.reload();
+ breakpoint.updateUI();
RequestManagerImpl.updateRequests(breakpoint);
if (myAllowMulticasting) {
// can be invoked from non-AWT thread
@@ -988,84 +949,103 @@ public class BreakpointManager {
}
public void setBreakpointEnabled(@NotNull final Breakpoint breakpoint, final boolean enabled) {
- if (breakpoint.ENABLED != enabled) {
- breakpoint.ENABLED = enabled;
- fireBreakpointChanged(breakpoint);
- breakpoint.updateUI();
+ if (breakpoint.isEnabled() != enabled) {
+ breakpoint.setEnabled(enabled);
+ //fireBreakpointChanged(breakpoint);
+ //breakpoint.updateUI();
}
}
public void addBreakpointRule(@NotNull EnableBreakpointRule rule) {
- rule.init();
- myBreakpointRules.add(rule);
+ //rule.init();
+ //myBreakpointRules.add(rule);
}
public boolean removeBreakpointRule(@NotNull EnableBreakpointRule rule) {
- final boolean removed = myBreakpointRules.remove(rule);
- if (removed) {
- rule.dispose();
- }
- return removed;
+ //final boolean removed = myBreakpointRules.remove(rule);
+ //if (removed) {
+ // rule.dispose();
+ //}
+ //return removed;
+ return false;
}
public boolean removeBreakpointRule(@NotNull Breakpoint slaveBreakpoint) {
- for (final EnableBreakpointRule rule : myBreakpointRules) {
- if (slaveBreakpoint.equals(rule.getSlaveBreakpoint())) {
- removeBreakpointRule(rule);
- return true;
- }
- }
+ //for (final EnableBreakpointRule rule : myBreakpointRules) {
+ // if (slaveBreakpoint.equals(rule.getSlaveBreakpoint())) {
+ // removeBreakpointRule(rule);
+ // return true;
+ // }
+ //}
return false;
}
- private void updateBreakpointRules(@NotNull Breakpoint removedBreakpoint) {
- for (Iterator<EnableBreakpointRule> it = myBreakpointRules.iterator(); it.hasNext();) {
- final EnableBreakpointRule rule = it.next();
- if (removedBreakpoint.equals(rule.getMasterBreakpoint()) || removedBreakpoint.equals(rule.getSlaveBreakpoint())) {
- it.remove();
- }
- }
- }
+ //private void updateBreakpointRules(@NotNull Breakpoint removedBreakpoint) {
+ // for (Iterator<EnableBreakpointRule> it = myBreakpointRules.iterator(); it.hasNext();) {
+ // final EnableBreakpointRule rule = it.next();
+ // if (removedBreakpoint.equals(rule.getMasterBreakpoint()) || removedBreakpoint.equals(rule.getSlaveBreakpoint())) {
+ // it.remove();
+ // }
+ // }
+ //}
+ // copied from XDebugSessionImpl processDependencies
public void processBreakpointHit(@NotNull final Breakpoint breakpoint) {
- for (final EnableBreakpointRule rule : myBreakpointRules) {
- rule.processBreakpointHit(breakpoint);
+ XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager();
+ XBreakpoint xBreakpoint = breakpoint.myXBreakpoint;
+ if (!dependentBreakpointManager.isMasterOrSlave(xBreakpoint)) {
+ return;
}
- }
-
- public void setInitialBreakpointsState() {
- myAllowMulticasting = false;
- for (final EnableBreakpointRule myBreakpointRule : myBreakpointRules) {
- myBreakpointRule.init();
+ List<XBreakpoint<?>> breakpoints = dependentBreakpointManager.getSlaveBreakpoints(xBreakpoint);
+ for (final XBreakpoint<?> slaveBreakpoint : breakpoints) {
+ DebuggerInvocationUtil.invokeLater(myProject, new Runnable() {
+ @Override
+ public void run() {
+ slaveBreakpoint.setEnabled(true);
+ }
+ });
}
- myAllowMulticasting = true;
- if (!myBreakpointRules.isEmpty()) {
- IJSwingUtilities.invoke(new Runnable() {
+
+ if (dependentBreakpointManager.getMasterBreakpoint(xBreakpoint) != null && !dependentBreakpointManager.isLeaveEnabled(xBreakpoint)) {
+ DebuggerInvocationUtil.invokeLater(myProject, new Runnable() {
@Override
public void run() {
- myDispatcher.getMulticaster().breakpointsChanged();
+ breakpoint.setEnabled(false);
}
});
+ //myDebuggerManager.getBreakpointManager().getLineBreakpointManager().queueBreakpointUpdate(breakpoint);
}
}
+
+ public void setInitialBreakpointsState() {
+ //myAllowMulticasting = false;
+ //for (final EnableBreakpointRule myBreakpointRule : myBreakpointRules) {
+ // myBreakpointRule.init();
+ //}
+ //myAllowMulticasting = true;
+ //if (!myBreakpointRules.isEmpty()) {
+ // IJSwingUtilities.invoke(new Runnable() {
+ // @Override
+ // public void run() {
+ // myDispatcher.getMulticaster().breakpointsChanged();
+ // }
+ // });
+ //}
+ }
@Nullable
public Breakpoint findMasterBreakpoint(@NotNull Breakpoint dependentBreakpoint) {
- for (final EnableBreakpointRule rule : myBreakpointRules) {
- if (dependentBreakpoint.equals(rule.getSlaveBreakpoint())) {
- return rule.getMasterBreakpoint();
- }
- }
- return null;
+ XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager();
+ return myBreakpoints.get(dependentBreakpointManager.getMasterBreakpoint(dependentBreakpoint.myXBreakpoint));
}
@Nullable
public EnableBreakpointRule findBreakpointRule(@NotNull Breakpoint dependentBreakpoint) {
- for (final EnableBreakpointRule rule : myBreakpointRules) {
- if (dependentBreakpoint.equals(rule.getSlaveBreakpoint())) {
- return rule;
- }
- }
+ //for (final EnableBreakpointRule rule : myBreakpointRules) {
+ // if (dependentBreakpoint.equals(rule.getSlaveBreakpoint())) {
+ // return rule;
+ // }
+ //}
return null;
}
@@ -1076,4 +1056,14 @@ public class BreakpointManager {
public String setProperty(String name, String value) {
return myUIProperties.put(name, value);
}
+
+ public static PsiFile getPsiFile(XBreakpoint xBreakpoint, Project project) {
+ try {
+ final Document document = FileDocumentManager.getInstance().getDocument(xBreakpoint.getSourcePosition().getFile());
+ return PsiDocumentManager.getInstance(project).getPsiFile(document);
+ } catch (Exception e) {
+ LOG.error(e);
+ }
+ return null;
+ }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
index d52044bbeb71..afeeb13aeb10 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
@@ -59,6 +59,9 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+/*
+ * Not used any more, since move to xBreakpoints
+ */
public abstract class BreakpointPropertiesPanel {
private BreakpointChooser myMasterBreakpointChooser;
@@ -208,8 +211,8 @@ public abstract class BreakpointPropertiesPanel {
final ItemListener suspendPolicyChangeListener = new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
- final BreakpointDefaults defaults = getBreakpointManager(myProject).getBreakpointDefaults(breakpointCategory);
- myMakeDefaultButton.setEnabled(!defaults.getSuspendPolicy().equals(getSelectedSuspendPolicy()) || defaults.isConditionEnabled() != myConditionCheckbox.isSelected());
+ //final BreakpointDefaults defaults = getBreakpointManager(myProject).getBreakpointDefaults(breakpointCategory);
+ //myMakeDefaultButton.setEnabled(!defaults.getSuspendPolicy().equals(getSelectedSuspendPolicy()) || defaults.isConditionEnabled() != myConditionCheckbox.isSelected());
}
};
@@ -426,13 +429,13 @@ public abstract class BreakpointPropertiesPanel {
}
private void updateSuspendPolicyRbFont() {
- final String defPolicy = getBreakpointManager(myProject).getBreakpointDefaults(myBreakpointCategory).getSuspendPolicy();
+ //final String defPolicy = getBreakpointManager(myProject).getBreakpointDefaults(myBreakpointCategory).getSuspendPolicy();
final Font font = myRbSuspendAll.getFont().deriveFont(Font.PLAIN);
final Font boldFont = font.deriveFont(Font.BOLD);
- myRbSuspendAll.setFont(DebuggerSettings.SUSPEND_ALL.equals(defPolicy)? boldFont : font);
- myRbSuspendThread.setFont(DebuggerSettings.SUSPEND_THREAD.equals(defPolicy)? boldFont : font);
+ //myRbSuspendAll.setFont(DebuggerSettings.SUSPEND_ALL.equals(defPolicy)? boldFont : font);
+ //myRbSuspendThread.setFont(DebuggerSettings.SUSPEND_THREAD.equals(defPolicy)? boldFont : font);
}
protected ClassFilter createClassConditionFilter() {
@@ -459,125 +462,126 @@ public abstract class BreakpointPropertiesPanel {
* Init UI components with the values from Breakpoint
*/
public void initFrom(Breakpoint breakpoint, boolean moreOptionsVisible1) {
- myBreakpoint = breakpoint;
- boolean moreOptionsVisible = moreOptionsVisible1;
- boolean actionsPanelVisible = moreOptionsVisible1;
-
- initMasterBreakpointPanel();
-
- if (breakpoint.COUNT_FILTER > 0) {
- myPassCountField.setText(Integer.toString(breakpoint.COUNT_FILTER));
- moreOptionsVisible = true;
- }
- else {
- myPassCountField.setText("");
- }
-
- PsiElement context = breakpoint.getEvaluationElement();
- myPassCountCheckbox.setSelected(breakpoint.COUNT_FILTER_ENABLED);
-
- myConditionCheckbox.setSelected(breakpoint.CONDITION_ENABLED);
-
- myConditionCombo.setEnabled(breakpoint.CONDITION_ENABLED);
-
- myConditionCombo.setContext(context);
- myConditionCombo.setText(breakpoint.getCondition() != null ? breakpoint.getCondition() : emptyText());
-
- myCbSuspend.setSelected(breakpoint.SUSPEND);
- myRbSuspendThread.setEnabled(myCbSuspend.isSelected());
- myRbSuspendAll.setEnabled(myCbSuspend.isSelected());
-
- if(!breakpoint.SUSPEND) {
- actionsPanelVisible = true;
- }
- if(DebuggerSettings.SUSPEND_THREAD.equals(breakpoint.SUSPEND_POLICY)){
- myRbSuspendThread.setSelected(true);
- }
- else {
- myRbSuspendAll.setSelected(true);
- }
-
- myCbSuspend.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent event) {
- if (!myActionsPanel.isVisible()) {
- if (!myCbSuspend.isSelected()) {
- if (myDelegate != null) {
- myDelegate.showActionsPanel();
- }
- }
- }
- myRbSuspendThread.setEnabled(myCbSuspend.isSelected());
- myRbSuspendAll.setEnabled(myCbSuspend.isSelected());
- }
- });
- myLogMessageCheckBox.setSelected(breakpoint.LOG_ENABLED);
- myTemporaryCheckBox.setSelected(breakpoint.REMOVE_AFTER_HIT);
- myEnabledCheckbox.setSelected(breakpoint.ENABLED);
- myEnabledCheckbox.setText(breakpoint.getShortName() + " enabled");
-
- DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().addBreakpointManagerListener(new BreakpointManagerListener() {
- @Override
- public void breakpointsChanged() {
- myEnabledCheckbox.setSelected(myBreakpoint.ENABLED);
- }
- });
-
- myEnabledCheckbox.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent event) {
- if (myBreakpoint.ENABLED != myEnabledCheckbox.isSelected()) {
- myBreakpoint.ENABLED = myEnabledCheckbox.isSelected();
- getBreakpointManager(myProject).fireBreakpointChanged(myBreakpoint);
- myBreakpoint.updateUI();
- }
- }
- });
- myTemporaryCheckBox.setVisible(breakpoint instanceof LineBreakpoint);
- myLogExpressionCheckBox.setSelected(breakpoint.LOG_EXPRESSION_ENABLED);
- if (breakpoint.LOG_ENABLED || breakpoint.LOG_EXPRESSION_ENABLED || (breakpoint instanceof LineBreakpoint && breakpoint.REMOVE_AFTER_HIT)) {
- actionsPanelVisible = true;
- }
-
- myLogExpressionCombo.setContext(context);
-
- if (breakpoint.getLogMessage() != null) {
- myLogExpressionCombo.setText(breakpoint.getLogMessage());
- }
- else {
- myLogExpressionCombo.setText(emptyText());
- }
-
- myLogExpressionCombo.setEnabled(breakpoint.LOG_EXPRESSION_ENABLED);
- if (breakpoint.LOG_EXPRESSION_ENABLED) {
- actionsPanelVisible = true;
- }
-
- myInstanceFiltersCheckBox.setSelected(breakpoint.INSTANCE_FILTERS_ENABLED);
- myInstanceFiltersField.setEnabled(breakpoint.INSTANCE_FILTERS_ENABLED);
- myInstanceFiltersField.getTextField().setEditable(breakpoint.INSTANCE_FILTERS_ENABLED);
- myInstanceFilters = breakpoint.getInstanceFilters();
- updateInstanceFilterEditor(true);
- if (breakpoint.INSTANCE_FILTERS_ENABLED) {
- moreOptionsVisible = true;
- }
-
- myClassFiltersCheckBox.setSelected(breakpoint.CLASS_FILTERS_ENABLED);
- myClassFiltersField.setEnabled(breakpoint.CLASS_FILTERS_ENABLED);
- myClassFiltersField.getTextField().setEditable(breakpoint.CLASS_FILTERS_ENABLED);
- myClassFilters = breakpoint.getClassFilters();
- myClassExclusionFilters = breakpoint.getClassExclusionFilters();
- updateClassFilterEditor(true);
- if (breakpoint.CLASS_FILTERS_ENABLED) {
- moreOptionsVisible = true;
- }
-
- myBreakpointPsiClass = breakpoint.getPsiClass();
-
- updateCheckboxes();
-
- setActionsPanelVisible(actionsPanelVisible && !moreOptionsVisible1);
- setMoreOptionsVisible(moreOptionsVisible);
+ //myBreakpoint = breakpoint;
+ //boolean moreOptionsVisible = moreOptionsVisible1;
+ //boolean actionsPanelVisible = moreOptionsVisible1;
+ //
+ //initMasterBreakpointPanel();
+ //
+ //if (breakpoint.getCountFilter() > 0) {
+ // myPassCountField.setText(Integer.toString(breakpoint.getCountFilter()));
+ // moreOptionsVisible = true;
+ //}
+ //else {
+ // myPassCountField.setText("");
+ //}
+ //
+ //PsiElement context = breakpoint.getEvaluationElement();
+ //myPassCountCheckbox.setSelected(breakpoint.isCountFilterEnabled());
+ //
+ //myConditionCheckbox.setSelected(breakpoint.isConditionEnabled());
+ //
+ //myConditionCombo.setEnabled(breakpoint.isConditionEnabled());
+ //
+ //myConditionCombo.setContext(context);
+ //myConditionCombo.setText(breakpoint.getCondition() != null ? breakpoint.getCondition() : emptyText());
+ //
+ //myCbSuspend.setSelected(breakpoint.isSuspend());
+ //myRbSuspendThread.setEnabled(myCbSuspend.isSelected());
+ //myRbSuspendAll.setEnabled(myCbSuspend.isSelected());
+ //
+ //if(!breakpoint.isSuspend()) {
+ // actionsPanelVisible = true;
+ //}
+ //if(DebuggerSettings.SUSPEND_THREAD.equals(breakpoint.getSuspendPolicy())){
+ // myRbSuspendThread.setSelected(true);
+ //}
+ //else {
+ // myRbSuspendAll.setSelected(true);
+ //}
+ //
+ //myCbSuspend.addActionListener(new ActionListener() {
+ // @Override
+ // public void actionPerformed(ActionEvent event) {
+ // if (!myActionsPanel.isVisible()) {
+ // if (!myCbSuspend.isSelected()) {
+ // if (myDelegate != null) {
+ // myDelegate.showActionsPanel();
+ // }
+ // }
+ // }
+ // myRbSuspendThread.setEnabled(myCbSuspend.isSelected());
+ // myRbSuspendAll.setEnabled(myCbSuspend.isSelected());
+ // }
+ //});
+ //myLogMessageCheckBox.setSelected(breakpoint.isLogEnabled());
+ //myTemporaryCheckBox.setSelected(breakpoint.isRemoveAfterHit());
+ //myEnabledCheckbox.setSelected(breakpoint.isEnabled());
+ //myEnabledCheckbox.setText(breakpoint.getShortName() + " enabled");
+ //
+ //DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().addBreakpointManagerListener(new BreakpointManagerListener() {
+ // @Override
+ // public void breakpointsChanged() {
+ // myEnabledCheckbox.setSelected(myBreakpoint.isEnabled());
+ // }
+ //});
+ //
+ //myEnabledCheckbox.addActionListener(new ActionListener() {
+ // @Override
+ // public void actionPerformed(ActionEvent event) {
+ // if (myBreakpoint.isEnabled() != myEnabledCheckbox.isSelected()) {
+ // myBreakpoint.setEnabled(myEnabledCheckbox.isSelected());
+ // getBreakpointManager(myProject).fireBreakpointChanged(myBreakpoint);
+ // myBreakpoint.updateUI();
+ // }
+ // }
+ //});
+ //myTemporaryCheckBox.setVisible(breakpoint instanceof LineBreakpoint);
+ //myLogExpressionCheckBox.setSelected(breakpoint.isLogExpressionEnabled());
+ //if (breakpoint.isLogEnabled() ||
+ // breakpoint.isLogExpressionEnabled() || (breakpoint instanceof LineBreakpoint && breakpoint.isRemoveAfterHit())) {
+ // actionsPanelVisible = true;
+ //}
+ //
+ //myLogExpressionCombo.setContext(context);
+ //
+ //if (breakpoint.getLogMessage() != null) {
+ // myLogExpressionCombo.setText(breakpoint.getLogMessage());
+ //}
+ //else {
+ // myLogExpressionCombo.setText(emptyText());
+ //}
+ //
+ //myLogExpressionCombo.setEnabled(breakpoint.isLogExpressionEnabled());
+ //if (breakpoint.isLogExpressionEnabled()) {
+ // actionsPanelVisible = true;
+ //}
+ //
+ //myInstanceFiltersCheckBox.setSelected(breakpoint.isInstanceFiltersEnabled());
+ //myInstanceFiltersField.setEnabled(breakpoint.isInstanceFiltersEnabled());
+ //myInstanceFiltersField.getTextField().setEditable(breakpoint.isInstanceFiltersEnabled());
+ //myInstanceFilters = breakpoint.getInstanceFilters();
+ //updateInstanceFilterEditor(true);
+ //if (breakpoint.isInstanceFiltersEnabled()) {
+ // moreOptionsVisible = true;
+ //}
+ //
+ //myClassFiltersCheckBox.setSelected(breakpoint.isClassFiltersEnabled());
+ //myClassFiltersField.setEnabled(breakpoint.isClassFiltersEnabled());
+ //myClassFiltersField.getTextField().setEditable(breakpoint.isClassFiltersEnabled());
+ //myClassFilters = breakpoint.getClassFilters();
+ //myClassExclusionFilters = breakpoint.getClassExclusionFilters();
+ //updateClassFilterEditor(true);
+ //if (breakpoint.isClassFiltersEnabled()) {
+ // moreOptionsVisible = true;
+ //}
+ //
+ //myBreakpointPsiClass = breakpoint.getPsiClass();
+ //
+ //updateCheckboxes();
+ //
+ //setActionsPanelVisible(actionsPanelVisible && !moreOptionsVisible1);
+ //setMoreOptionsVisible(moreOptionsVisible);
}
private void initMasterBreakpointPanel() {
@@ -632,41 +636,41 @@ public abstract class BreakpointPropertiesPanel {
*/
public void saveTo(Breakpoint breakpoint) {
- saveMasterBreakpoint();
- try {
- String text = myPassCountField.getText().trim();
- breakpoint.COUNT_FILTER = !text.isEmpty() ? Integer.parseInt(text) : 0;
- if (breakpoint.COUNT_FILTER < 0) {
- breakpoint.COUNT_FILTER = 0;
- }
- }
- catch (Exception ignored) {
- }
-
- breakpoint.COUNT_FILTER_ENABLED = breakpoint.COUNT_FILTER > 0 && myPassCountCheckbox.isSelected();
- breakpoint.setCondition(myConditionCombo.getText());
- breakpoint.CONDITION_ENABLED = myConditionCheckbox.isSelected();
- breakpoint.setLogMessage(myLogExpressionCombo.getText());
- breakpoint.LOG_EXPRESSION_ENABLED = !breakpoint.getLogMessage().isEmpty() && myLogExpressionCheckBox.isSelected();
- breakpoint.LOG_ENABLED = myLogMessageCheckBox.isSelected();
- breakpoint.ENABLED = myEnabledCheckbox.isSelected();
- breakpoint.REMOVE_AFTER_HIT = myTemporaryCheckBox.isSelected();
- breakpoint.SUSPEND = myCbSuspend.isSelected();
- breakpoint.SUSPEND_POLICY = getSelectedSuspendPolicy();
- reloadInstanceFilters();
- reloadClassFilters();
- updateInstanceFilterEditor(true);
- updateClassFilterEditor(true);
-
- breakpoint.INSTANCE_FILTERS_ENABLED = myInstanceFiltersField.getText().length() > 0 && myInstanceFiltersCheckBox.isSelected();
- breakpoint.CLASS_FILTERS_ENABLED = myClassFiltersField.getText().length() > 0 && myClassFiltersCheckBox.isSelected();
- breakpoint.setClassFilters(myClassFilters);
- breakpoint.setClassExclusionFilters(myClassExclusionFilters);
- breakpoint.setInstanceFilters(myInstanceFilters);
-
- myConditionCombo.addRecent(myConditionCombo.getText());
- myLogExpressionCombo.addRecent(myLogExpressionCombo.getText());
- breakpoint.updateUI();
+ //saveMasterBreakpoint();
+ //try {
+ // String text = myPassCountField.getText().trim();
+ // breakpoint.setCountFilter(!text.isEmpty() ? Integer.parseInt(text) : 0);
+ // if (breakpoint.getCountFilter() < 0) {
+ // breakpoint.setCountFilter(0);
+ // }
+ //}
+ //catch (Exception ignored) {
+ //}
+ //
+ //breakpoint.setCountFilterEnabled(breakpoint.getCountFilter() > 0 && myPassCountCheckbox.isSelected());
+ //breakpoint.setCondition(myConditionCombo.getText().getText());
+ ////breakpoint.setConditionEnabled(myConditionCheckbox.isSelected());
+ //breakpoint.setLogMessage(myLogExpressionCombo.getText());
+ //breakpoint.setLogExpressionEnabled(!breakpoint.getLogMessage().isEmpty() && myLogExpressionCheckBox.isSelected());
+ //breakpoint.setLogEnabled(myLogMessageCheckBox.isSelected());
+ //breakpoint.setEnabled(myEnabledCheckbox.isSelected());
+ //breakpoint.setRemoveAfterHit(myTemporaryCheckBox.isSelected());
+ ////breakpoint.setSuspend(myCbSuspend.isSelected());
+ //breakpoint.setSuspendPolicy(getSelectedSuspendPolicy());
+ //reloadInstanceFilters();
+ //reloadClassFilters();
+ //updateInstanceFilterEditor(true);
+ //updateClassFilterEditor(true);
+ //
+ //breakpoint.setInstanceFiltersEnabled(myInstanceFiltersField.getText().length() > 0 && myInstanceFiltersCheckBox.isSelected());
+ //breakpoint.setClassFiltersEnabled(myClassFiltersField.getText().length() > 0 && myClassFiltersCheckBox.isSelected());
+ //breakpoint.setClassFilters(myClassFilters);
+ //breakpoint.setClassExclusionFilters(myClassExclusionFilters);
+ //breakpoint.setInstanceFilters(myInstanceFilters);
+ //
+ //myConditionCombo.addRecent(myConditionCombo.getText());
+ //myLogExpressionCombo.addRecent(myLogExpressionCombo.getText());
+ //breakpoint.updateUI();
}
private static String concatWithEx(List<String> s, String concator, int N, String NthConcator) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java
index 16b75279099e..8cd1bfbe8151 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java
@@ -25,49 +25,49 @@ import com.intellij.debugger.engine.events.DebuggerCommandImpl;
import com.intellij.debugger.engine.requests.RequestManagerImpl;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.settings.DebuggerSettings;
-import com.intellij.debugger.ui.JavaDebuggerSupport;
-import com.intellij.openapi.actionSystem.ActionGroup;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.MarkupModelEx;
import com.intellij.openapi.editor.impl.DocumentMarkupModel;
-import com.intellij.openapi.editor.markup.*;
+import com.intellij.openapi.editor.markup.MarkupEditorFilterFactory;
+import com.intellij.openapi.editor.markup.RangeHighlighter;
+import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.jsp.JspFile;
-import com.intellij.ui.AppUIUtil;
import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.util.StringBuilderSpinAllocator;
-import com.intellij.xdebugger.impl.DebuggerSupport;
-import com.intellij.xdebugger.impl.actions.EditBreakpointAction;
+import com.intellij.xdebugger.XDebuggerManager;
+import com.intellij.xdebugger.XSourcePosition;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.XBreakpointManager;
+import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
import com.intellij.xdebugger.ui.DebuggerColors;
import com.intellij.xml.util.XmlStringUtil;
import com.sun.jdi.ReferenceType;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties;
import javax.swing.*;
-import java.awt.*;
-import java.awt.dnd.DragSource;
/**
* User: lex
* Date: Sep 2, 2003
* Time: 3:22:55 PM
*/
-public abstract class BreakpointWithHighlighter extends Breakpoint {
+public abstract class BreakpointWithHighlighter<P extends JavaBreakpointProperties> extends Breakpoint<P> {
@Nullable
private RangeHighlighter myHighlighter;
@@ -150,7 +150,7 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
private Icon calcIcon(@Nullable DebugProcessImpl debugProcess) {
final boolean muted = debugProcess != null && isMuted(debugProcess);
- if (!ENABLED) {
+ if (!isEnabled()) {
return getDisabledIcon(muted);
}
@@ -184,13 +184,14 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
return getSetIcon(muted);
}
- protected BreakpointWithHighlighter(@NotNull Project project) {
+ protected BreakpointWithHighlighter(@NotNull Project project, XBreakpoint xBreakpoint) {
//for persistency
- super(project);
+ super(project, xBreakpoint);
+ reload();
}
- public BreakpointWithHighlighter(@NotNull final Project project, @NotNull final RangeHighlighter highlighter) {
- super(project);
+ public BreakpointWithHighlighter(@NotNull final Project project, @NotNull final RangeHighlighter highlighter, XBreakpoint breakpoint) {
+ super(project, breakpoint);
myHighlighter = highlighter;
setEditorFilter(highlighter);
reload();
@@ -208,10 +209,10 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
@Override
public boolean isValid() {
- return isPositionValid(getSourcePosition());
+ return isPositionValid(myXBreakpoint.getSourcePosition());
}
- private static boolean isPositionValid(@Nullable final SourcePosition sourcePosition) {
+ protected static boolean isPositionValid(@Nullable final XSourcePosition sourcePosition) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
@@ -238,34 +239,34 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
}
buf.append("&nbsp;<br>&nbsp;");
buf.append(DebuggerBundle.message("breakpoint.property.name.suspend.policy")).append(" : ");
- if (DebuggerSettings.SUSPEND_NONE.equals(SUSPEND_POLICY) || !SUSPEND) {
+ if (DebuggerSettings.SUSPEND_NONE.equals(getSuspendPolicy()) || !isSuspend()) {
buf.append(DebuggerBundle.message("breakpoint.properties.panel.option.suspend.none"));
}
- else if (DebuggerSettings.SUSPEND_ALL.equals(SUSPEND_POLICY)) {
+ else if (DebuggerSettings.SUSPEND_ALL.equals(getSuspendPolicy())) {
buf.append(DebuggerBundle.message("breakpoint.properties.panel.option.suspend.all"));
}
- else if (DebuggerSettings.SUSPEND_THREAD.equals(SUSPEND_POLICY)) {
+ else if (DebuggerSettings.SUSPEND_THREAD.equals(getSuspendPolicy())) {
buf.append(DebuggerBundle.message("breakpoint.properties.panel.option.suspend.thread"));
}
buf.append("&nbsp;<br>&nbsp;");
buf.append(DebuggerBundle.message("breakpoint.property.name.log.message")).append(": ");
- buf.append(LOG_ENABLED ? CommonBundle.getYesButtonText() : CommonBundle.getNoButtonText());
- if (LOG_EXPRESSION_ENABLED) {
+ buf.append(isLogEnabled() ? CommonBundle.getYesButtonText() : CommonBundle.getNoButtonText());
+ if (isLogExpressionEnabled()) {
buf.append("&nbsp;<br>&nbsp;");
buf.append(DebuggerBundle.message("breakpoint.property.name.log.expression")).append(": ");
buf.append(XmlStringUtil.escapeString(getLogMessage().getText()));
}
- if (CONDITION_ENABLED && getCondition() != null && getCondition().getText() != null && !getCondition().getText().isEmpty()) {
+ if (isConditionEnabled() && getCondition() != null && getCondition().getText() != null && !getCondition().getText().isEmpty()) {
buf.append("&nbsp;<br>&nbsp;");
buf.append(DebuggerBundle.message("breakpoint.property.name.condition")).append(": ");
buf.append(XmlStringUtil.escapeString(getCondition().getText()));
}
- if (COUNT_FILTER_ENABLED) {
+ if (isCountFilterEnabled()) {
buf.append("&nbsp;<br>&nbsp;");
buf.append(DebuggerBundle.message("breakpoint.property.name.pass.count")).append(": ");
- buf.append(COUNT_FILTER);
+ buf.append(getCountFilter());
}
- if (CLASS_FILTERS_ENABLED) {
+ if (isClassFiltersEnabled()) {
buf.append("&nbsp;<br>&nbsp;");
buf.append(DebuggerBundle.message("breakpoint.property.name.class.filters")).append(": ");
ClassFilter[] classFilters = getClassFilters();
@@ -273,7 +274,7 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
buf.append(classFilter.getPattern()).append(" ");
}
}
- if (INSTANCE_FILTERS_ENABLED) {
+ if (isInstanceFiltersEnabled()) {
buf.append("&nbsp;<br>&nbsp;");
buf.append(DebuggerBundle.message("breakpoint.property.name.instance.filters"));
InstanceFilter[] instanceFilters = getInstanceFilters();
@@ -290,25 +291,23 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
}
@Override
- public final void reload() {
+ public void reload() {
ApplicationManager.getApplication().assertReadAccessAllowed();
- RangeHighlighter highlighter = myHighlighter;
- if (highlighter != null && highlighter.isValid()) {
- PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(highlighter.getDocument());
- if (psiFile != null) {
- mySourcePosition = SourcePosition.createFromOffset(psiFile, highlighter.getStartOffset());
- reload(psiFile);
- return;
- }
+ final XSourcePosition position = myXBreakpoint.getSourcePosition();
+ try {
+ final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(position.getFile());
+ mySourcePosition = SourcePosition.createFromOffset(psiFile, position.getOffset());
+ } catch (Exception e) {
+ mySourcePosition = null;
}
- mySourcePosition = null;
+ reload(BreakpointManager.getPsiFile(myXBreakpoint, myProject));
}
@Override
public void createRequest(@NotNull DebugProcessImpl debugProcess) {
DebuggerManagerThreadImpl.assertIsManagerThread();
// check is this breakpoint is enabled, vm reference is valid and there're no requests created yet
- if (!ENABLED ||
+ if (!isEnabled() ||
!debugProcess.isAttached() ||
isMuted(debugProcess) ||
!debugProcess.getRequestsManager().findRequests(this).isEmpty()) {
@@ -329,7 +328,7 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
@Override
public void processClassPrepare(final DebugProcess debugProcess, final ReferenceType classType) {
- if (!ENABLED || !isValid()) {
+ if (!isEnabled() || !isValid()) {
return;
}
createRequestForPreparedClass((DebugProcessImpl)debugProcess, classType);
@@ -383,20 +382,24 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
private void updateGutter() {
if (myVisible) {
- RangeHighlighter highlighter = myHighlighter;
- if (highlighter != null && highlighter.isValid() && isValid()) {
- AppUIUtil.invokeLaterIfProjectAlive(myProject, new Runnable() {
- @Override
- public void run() {
- if (isValid()) {
- setupGutterRenderer(myHighlighter);
- }
- }
- });
- }
- else {
- DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(this);
+ if (isValid()) {
+ final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(myProject).getBreakpointManager();
+ breakpointManager.updateBreakpointPresentation((XLineBreakpoint)myXBreakpoint, getIcon(), null);
}
+ //RangeHighlighter highlighter = myHighlighter;
+ //if (highlighter != null && highlighter.isValid() && isValid()) {
+ // AppUIUtil.invokeLaterIfProjectAlive(myProject, new Runnable() {
+ // @Override
+ // public void run() {
+ // if (isValid()) {
+ // setupGutterRenderer(myHighlighter);
+ // }
+ // }
+ // });
+ //}
+ //else {
+ // DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(this);
+ //}
}
}
@@ -422,11 +425,10 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
}
public boolean isAt(@NotNull Document document, int offset) {
- RangeHighlighter highlighter = getHighlighter();
- return highlighter != null &&
- highlighter.isValid() &&
- document.equals(highlighter.getDocument()) &&
- getSourcePosition().getLine() == document.getLineNumber(offset);
+ final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
+ int line = document.getLineNumber(offset);
+ XSourcePosition position = myXBreakpoint.getSourcePosition();
+ return position != null && position.getLine() == line && position.getFile().equals(file);
}
protected void reload(PsiFile psiFile) {
@@ -448,9 +450,9 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
});
}
- private void setupGutterRenderer(@NotNull RangeHighlighter highlighter) {
- highlighter.setGutterIconRenderer(new MyGutterIconRenderer(getIcon(), getDescription()));
- }
+ //private void setupGutterRenderer(@NotNull RangeHighlighter highlighter) {
+ // highlighter.setGutterIconRenderer(new MyGutterIconRenderer(getIcon(), getDescription()));
+ //}
@Override
public abstract Key<? extends BreakpointWithHighlighter> getCategory();
@@ -559,7 +561,7 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
public void readExternal(@NotNull Element breakpointNode) throws InvalidDataException {
super.readExternal(breakpointNode);
//noinspection HardCodedStringLiteral
- final String url = breakpointNode.getAttributeValue("url");
+ //final String url = breakpointNode.getAttributeValue("url");
//noinspection HardCodedStringLiteral
final String className = breakpointNode.getAttributeValue("class");
@@ -573,146 +575,146 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
myPackageName = packageName;
}
- VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(url);
- if (vFile == null) {
- throw new InvalidDataException(DebuggerBundle.message("error.breakpoint.file.not.found", url));
- }
- final Document doc = FileDocumentManager.getInstance().getDocument(vFile);
- if (doc == null) {
- throw new InvalidDataException(DebuggerBundle.message("error.cannot.load.breakpoint.file", url));
- }
-
- // line number
- final int line;
- try {
- //noinspection HardCodedStringLiteral
- line = Integer.parseInt(breakpointNode.getAttributeValue("line"));
- }
- catch (Exception e) {
- throw new InvalidDataException("Line number is invalid for breakpoint");
- }
- if (line < 0) {
- throw new InvalidDataException("Line number is invalid for breakpoint");
- }
-
- RangeHighlighter highlighter = createHighlighter(myProject, doc, line);
-
- if (highlighter == null) {
- throw new InvalidDataException("");
- }
-
- myHighlighter = highlighter;
- reload();
- }
-
- @Override
- @SuppressWarnings({"HardCodedStringLiteral"})
- public void writeExternal(@NotNull Element parentNode) throws WriteExternalException {
- super.writeExternal(parentNode);
- PsiFile psiFile = getSourcePosition().getFile();
- final VirtualFile virtualFile = psiFile.getVirtualFile();
- final String url = virtualFile != null ? virtualFile.getUrl() : "";
- parentNode.setAttribute("url", url);
- parentNode.setAttribute("line", Integer.toString(getSourcePosition().getLine()));
- if (myClassName != null) {
- parentNode.setAttribute("class", myClassName);
- }
- if (myPackageName != null) {
- parentNode.setAttribute("package", myPackageName);
- }
- }
-
- private class MyGutterIconRenderer extends GutterIconRenderer {
- private final Icon myIcon;
- private final String myDescription;
-
- public MyGutterIconRenderer(@NotNull Icon icon, @NotNull String description) {
- myIcon = icon;
- myDescription = description;
- }
-
- @Override
- @NotNull
- public Icon getIcon() {
- return myIcon;
- }
-
- @Override
- public String getTooltipText() {
- return myDescription;
- }
-
- @Override
- public Alignment getAlignment() {
- return Alignment.RIGHT;
- }
-
- @Override
- public AnAction getClickAction() {
- return new AnAction() {
- @Override
- public void actionPerformed(AnActionEvent e) {
- DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(BreakpointWithHighlighter.this);
- }
- };
- }
-
- @Override
- public AnAction getMiddleButtonClickAction() {
- return new AnAction() {
- @Override
- public void actionPerformed(AnActionEvent e) {
- ENABLED = !ENABLED;
- DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager().fireBreakpointChanged(BreakpointWithHighlighter.this);
- updateUI();
- }
- };
- }
-
- @Override
- public ActionGroup getPopupMenuActions() {
- return null;
- }
-
- @Nullable
- @Override
- public AnAction getRightButtonClickAction() {
- return new EditBreakpointAction.ContextAction(this, BreakpointWithHighlighter.this, DebuggerSupport.getDebuggerSupport(JavaDebuggerSupport.class));
- }
-
- @Override
- public GutterDraggableObject getDraggableObject() {
- return new GutterDraggableObject() {
- @Override
- public boolean copy(int line, @NotNull VirtualFile file) {
- final PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(file);
- return psiFile != null && moveTo(SourcePosition.createFromLine(psiFile, line));
- }
-
- @Override
- public Cursor getCursor(int line) {
- final SourcePosition newPosition = SourcePosition.createFromLine(getSourcePosition().getFile(), line);
- return canMoveTo(newPosition) ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop;
- }
- };
- }
-
- @Override
- public boolean equals(@NotNull Object obj) {
- return obj instanceof MyGutterIconRenderer &&
- Comparing.equal(getTooltipText(), ((MyGutterIconRenderer)obj).getTooltipText()) &&
- Comparing.equal(getIcon(), ((MyGutterIconRenderer)obj).getIcon());
- }
-
- @Override
- public int hashCode() {
- return getIcon().hashCode();
- }
-
- @Override
- public String toString() {
- return "LB " + getDisplayName();
- }
- }
+ //VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(url);
+ //if (vFile == null) {
+ // throw new InvalidDataException(DebuggerBundle.message("error.breakpoint.file.not.found", url));
+ //}
+ //final Document doc = FileDocumentManager.getInstance().getDocument(vFile);
+ //if (doc == null) {
+ // throw new InvalidDataException(DebuggerBundle.message("error.cannot.load.breakpoint.file", url));
+ //}
+ //
+ //// line number
+ //final int line;
+ //try {
+ // //noinspection HardCodedStringLiteral
+ // line = Integer.parseInt(breakpointNode.getAttributeValue("line"));
+ //}
+ //catch (Exception e) {
+ // throw new InvalidDataException("Line number is invalid for breakpoint");
+ //}
+ //if (line < 0) {
+ // throw new InvalidDataException("Line number is invalid for breakpoint");
+ //}
+ //
+ //RangeHighlighter highlighter = createHighlighter(myProject, doc, line);
+ //
+ //if (highlighter == null) {
+ // throw new InvalidDataException("");
+ //}
+ //
+ //myHighlighter = highlighter;
+ //reload();
+ }
+ //
+ //@Override
+ //@SuppressWarnings({"HardCodedStringLiteral"})
+ //public void writeExternal(@NotNull Element parentNode) throws WriteExternalException {
+ // super.writeExternal(parentNode);
+ // PsiFile psiFile = getSourcePosition().getFile();
+ // final VirtualFile virtualFile = psiFile.getVirtualFile();
+ // final String url = virtualFile != null ? virtualFile.getUrl() : "";
+ // parentNode.setAttribute("url", url);
+ // parentNode.setAttribute("line", Integer.toString(getSourcePosition().getLine()));
+ // if (myClassName != null) {
+ // parentNode.setAttribute("class", myClassName);
+ // }
+ // if (myPackageName != null) {
+ // parentNode.setAttribute("package", myPackageName);
+ // }
+ //}
+
+ //private class MyGutterIconRenderer extends GutterIconRenderer {
+ // private final Icon myIcon;
+ // private final String myDescription;
+ //
+ // public MyGutterIconRenderer(@NotNull Icon icon, @NotNull String description) {
+ // myIcon = icon;
+ // myDescription = description;
+ // }
+ //
+ // @Override
+ // @NotNull
+ // public Icon getIcon() {
+ // return myIcon;
+ // }
+ //
+ // @Override
+ // public String getTooltipText() {
+ // return myDescription;
+ // }
+ //
+ // @Override
+ // public Alignment getAlignment() {
+ // return Alignment.RIGHT;
+ // }
+ //
+ // @Override
+ // public AnAction getClickAction() {
+ // return new AnAction() {
+ // @Override
+ // public void actionPerformed(AnActionEvent e) {
+ // DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(BreakpointWithHighlighter.this);
+ // }
+ // };
+ // }
+ //
+ // @Override
+ // public AnAction getMiddleButtonClickAction() {
+ // return new AnAction() {
+ // @Override
+ // public void actionPerformed(AnActionEvent e) {
+ // setEnabled(!isEnabled());
+ // DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager().fireBreakpointChanged(BreakpointWithHighlighter.this);
+ // updateUI();
+ // }
+ // };
+ // }
+ //
+ // @Override
+ // public ActionGroup getPopupMenuActions() {
+ // return null;
+ // }
+ //
+ // @Nullable
+ // @Override
+ // public AnAction getRightButtonClickAction() {
+ // return new EditBreakpointAction.ContextAction(this, BreakpointWithHighlighter.this, DebuggerSupport.getDebuggerSupport(JavaDebuggerSupport.class));
+ // }
+ //
+ // @Override
+ // public GutterDraggableObject getDraggableObject() {
+ // return new GutterDraggableObject() {
+ // @Override
+ // public boolean copy(int line, @NotNull VirtualFile file) {
+ // final PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(file);
+ // return psiFile != null && moveTo(SourcePosition.createFromLine(psiFile, line));
+ // }
+ //
+ // @Override
+ // public Cursor getCursor(int line) {
+ // final SourcePosition newPosition = SourcePosition.createFromLine(getSourcePosition().getFile(), line);
+ // return canMoveTo(newPosition) ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop;
+ // }
+ // };
+ // }
+ //
+ // @Override
+ // public boolean equals(@NotNull Object obj) {
+ // return obj instanceof MyGutterIconRenderer &&
+ // Comparing.equal(getTooltipText(), ((MyGutterIconRenderer)obj).getTooltipText()) &&
+ // Comparing.equal(getIcon(), ((MyGutterIconRenderer)obj).getIcon());
+ // }
+ //
+ // @Override
+ // public int hashCode() {
+ // return getIcon().hashCode();
+ // }
+ //
+ // @Override
+ // public String toString() {
+ // return "LB " + getDisplayName();
+ // }
+ //}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java
index c6a19557f4e8..8a0b5159d5f7 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java
@@ -34,13 +34,14 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizerUtil;
import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.Location;
import com.sun.jdi.ObjectReference;
@@ -50,36 +51,32 @@ import com.sun.jdi.event.LocatableEvent;
import com.sun.jdi.request.ExceptionRequest;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaExceptionBreakpointProperties;
import javax.swing.*;
-public class ExceptionBreakpoint extends Breakpoint {
+public class ExceptionBreakpoint extends Breakpoint<JavaExceptionBreakpointProperties> {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.ExceptionBreakpoint");
- public boolean NOTIFY_CAUGHT = true;
- public boolean NOTIFY_UNCAUGHT = true;
- private String myQualifiedName;
- private String myPackageName;
-
protected final static String READ_NO_CLASS_NAME = DebuggerBundle.message("error.absent.exception.breakpoint.class.name");
public static final @NonNls Key<ExceptionBreakpoint> CATEGORY = BreakpointCategory.lookup("exception_breakpoints");
- public ExceptionBreakpoint(Project project) {
- super(project);
+ public ExceptionBreakpoint(Project project, XBreakpoint xBreakpoint) {
+ super(project, xBreakpoint);
}
public Key<? extends ExceptionBreakpoint> getCategory() {
return CATEGORY;
}
- protected ExceptionBreakpoint(Project project, String qualifiedName, String packageName) {
- super(project);
- myQualifiedName = qualifiedName;
+ protected ExceptionBreakpoint(Project project, String qualifiedName, String packageName, XBreakpoint xBreakpoint) {
+ super(project, xBreakpoint);
+ setQualifiedName(qualifiedName);
if (packageName == null) {
- myPackageName = calcPackageName(qualifiedName);
+ setPackageName(calcPackageName(qualifiedName));
}
else {
- myPackageName = packageName;
+ setPackageName(packageName);
}
}
@@ -92,27 +89,27 @@ public class ExceptionBreakpoint extends Breakpoint {
}
public String getClassName() {
- return myQualifiedName;
+ return getQualifiedName();
}
public String getPackageName() {
- return myPackageName;
+ return getProperties().myPackageName;
}
public PsiClass getPsiClass() {
return PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Computable<PsiClass>() {
public PsiClass compute() {
- return myQualifiedName != null ? DebuggerUtilsEx.findClass(myQualifiedName, myProject, GlobalSearchScope.allScope(myProject)) : null;
+ return getQualifiedName() != null ? DebuggerUtilsEx.findClass(getQualifiedName(), myProject, GlobalSearchScope.allScope(myProject)) : null;
}
});
}
public String getDisplayName() {
- return DebuggerBundle.message("breakpoint.exception.breakpoint.display.name", myQualifiedName);
+ return DebuggerBundle.message("breakpoint.exception.breakpoint.display.name", getQualifiedName());
}
public Icon getIcon() {
- if (!ENABLED) {
+ if (!isEnabled()) {
final Breakpoint master = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().findMasterBreakpoint(this);
return master == null? AllIcons.Debugger.Db_disabled_exception_breakpoint : AllIcons.Debugger.Db_dep_exception_breakpoint;
}
@@ -124,20 +121,20 @@ public class ExceptionBreakpoint extends Breakpoint {
public void createRequest(final DebugProcessImpl debugProcess) {
DebuggerManagerThreadImpl.assertIsManagerThread();
- if (!ENABLED || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) {
+ if (!isEnabled() || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) {
return;
}
SourcePosition classPosition = PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Computable<SourcePosition>() {
public SourcePosition compute() {
- PsiClass psiClass = DebuggerUtilsEx.findClass(myQualifiedName, myProject, debugProcess.getSearchScope());
+ PsiClass psiClass = DebuggerUtilsEx.findClass(getQualifiedName(), myProject, debugProcess.getSearchScope());
return psiClass != null ? SourcePosition.createFromElement(psiClass) : null;
}
});
if(classPosition == null) {
- createOrWaitPrepare(debugProcess, myQualifiedName);
+ createOrWaitPrepare(debugProcess, getQualifiedName());
}
else {
createOrWaitPrepare(debugProcess, classPosition);
@@ -146,11 +143,12 @@ public class ExceptionBreakpoint extends Breakpoint {
public void processClassPrepare(DebugProcess process, ReferenceType refType) {
DebugProcessImpl debugProcess = (DebugProcessImpl)process;
- if (!ENABLED) {
+ if (!isEnabled()) {
return;
}
// trying to create a request
- ExceptionRequest request = debugProcess.getRequestsManager().createExceptionRequest(this, refType, NOTIFY_CAUGHT, NOTIFY_UNCAUGHT);
+ ExceptionRequest request = debugProcess.getRequestsManager().createExceptionRequest(this, refType, isNotifyCaught(),
+ isNotifyUncaught());
debugProcess.getRequestsManager().enableRequest(request);
if (LOG.isDebugEnabled()) {
if (refType != null) {
@@ -170,7 +168,7 @@ public class ExceptionBreakpoint extends Breakpoint {
}
public String getEventMessage(LocatableEvent event) {
- String exceptionName = (myQualifiedName != null)? myQualifiedName : "java.lang.Throwable";
+ String exceptionName = (getQualifiedName() != null)? getQualifiedName() : "java.lang.Throwable";
String threadName = null;
if (event instanceof ExceptionEvent) {
ExceptionEvent exceptionEvent = (ExceptionEvent)event;
@@ -216,15 +214,15 @@ public class ExceptionBreakpoint extends Breakpoint {
return true;
}
- @SuppressWarnings({"HardCodedStringLiteral"}) public void writeExternal(Element parentNode) throws WriteExternalException {
- super.writeExternal(parentNode);
- if(myQualifiedName != null) {
- parentNode.setAttribute("class_name", myQualifiedName);
- }
- if(myPackageName != null) {
- parentNode.setAttribute("package_name", myPackageName);
- }
- }
+ //@SuppressWarnings({"HardCodedStringLiteral"}) public void writeExternal(Element parentNode) throws WriteExternalException {
+ // super.writeExternal(parentNode);
+ // if(getQualifiedName() != null) {
+ // parentNode.setAttribute("class_name", getQualifiedName());
+ // }
+ // if(getPackageName() != null) {
+ // parentNode.setAttribute("package_name", getPackageName());
+ // }
+ //}
public PsiElement getEvaluationElement() {
if (getClassName() == null) {
@@ -235,16 +233,45 @@ public class ExceptionBreakpoint extends Breakpoint {
public void readExternal(Element parentNode) throws InvalidDataException {
super.readExternal(parentNode);
+
+ //noinspection HardCodedStringLiteral
+ String packageName = parentNode.getAttributeValue("package_name");
+ setPackageName(packageName != null? packageName : calcPackageName(packageName));
+
+ try {
+ getProperties().NOTIFY_CAUGHT = Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "NOTIFY_CAUGHT"));
+ } catch (Exception e) {
+ }
+ try {
+ getProperties().NOTIFY_UNCAUGHT = Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "NOTIFY_UNCAUGHT"));
+ } catch (Exception e) {
+ }
+
//noinspection HardCodedStringLiteral
String className = parentNode.getAttributeValue("class_name");
- myQualifiedName = className;
+ setQualifiedName(className);
if(className == null) {
throw new InvalidDataException(READ_NO_CLASS_NAME);
}
+ }
- //noinspection HardCodedStringLiteral
- String packageName = parentNode.getAttributeValue("package_name");
- myPackageName = packageName != null? packageName : calcPackageName(packageName);
+ private boolean isNotifyCaught() {
+ return getProperties().NOTIFY_CAUGHT;
+ }
+
+ private boolean isNotifyUncaught() {
+ return getProperties().NOTIFY_UNCAUGHT;
}
+ private String getQualifiedName() {
+ return getProperties().myQualifiedName;
+ }
+
+ private void setQualifiedName(String qualifiedName) {
+ getProperties().myQualifiedName = qualifiedName;
+ }
+
+ private void setPackageName(String packageName) {
+ getProperties().myPackageName = packageName;
+ }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java
deleted file mode 100644
index 40b75c4ffc71..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointFactory.java
+++ /dev/null
@@ -1,94 +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.ui.breakpoints;
-
-import com.intellij.debugger.DebuggerBundle;
-import com.intellij.debugger.DebuggerManagerEx;
-import com.intellij.debugger.HelpID;
-import com.intellij.debugger.engine.JVMNameUtil;
-import com.intellij.icons.AllIcons;
-import com.intellij.ide.util.TreeClassChooser;
-import com.intellij.ide.util.TreeClassChooserFactory;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Key;
-import com.intellij.psi.JavaPsiFacade;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiClassOwner;
-import com.intellij.psi.search.GlobalSearchScope;
-import org.jdom.Element;
-
-import javax.swing.*;
-
-/**
- * @author Eugene Zhuravlev
- * Date: Apr 26, 2005
- */
-public class ExceptionBreakpointFactory extends BreakpointFactory {
- public Breakpoint createBreakpoint(Project project, final Element element) {
- return new ExceptionBreakpoint(project);
- }
-
- public Icon getIcon() {
- return AllIcons.Debugger.Db_exception_breakpoint;
- }
-
- public Icon getDisabledIcon() {
- return AllIcons.Debugger.Db_disabled_exception_breakpoint;
- }
-
- @Override
- protected String getHelpID() {
- return HelpID.EXCEPTION_BREAKPOINTS;
- }
-
- @Override
- public String getDisplayName() {
- return DebuggerBundle.message("exception.breakpoints.tab.title");
- }
-
- @Override
- public BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact) {
- return new ExceptionBreakpointPropertiesPanel(project, compact);
- }
-
- public Key<ExceptionBreakpoint> getBreakpointCategory() {
- return ExceptionBreakpoint.CATEGORY;
- }
-
- @Override
- public boolean canAddBreakpoints() {
- return true;
- }
-
- @Override
- public Breakpoint addBreakpoint(Project project) {
- ExceptionBreakpoint breakpoint = null;
- final PsiClass throwableClass =
- JavaPsiFacade.getInstance(project).findClass("java.lang.Throwable", GlobalSearchScope.allScope(project));
- TreeClassChooser chooser = TreeClassChooserFactory.getInstance(project)
- .createInheritanceClassChooser(DebuggerBundle.message("add.exception.breakpoint.classchooser.title"),
- GlobalSearchScope.allScope(project), throwableClass, true, true, null);
- chooser.showDialog();
- PsiClass selectedClass = chooser.getSelected();
- String qName = selectedClass == null ? null : JVMNameUtil.getNonAnonymousClassName(selectedClass);
-
- if (qName != null && qName.length() > 0) {
- breakpoint = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager()
- .addExceptionBreakpoint(qName, ((PsiClassOwner)selectedClass.getContainingFile()).getPackageName());
- }
- return breakpoint;
- }
-}
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 6d02499f227c..4af7275d1258 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
@@ -21,31 +21,34 @@
package com.intellij.debugger.ui.breakpoints;
import com.intellij.debugger.DebuggerBundle;
-import com.intellij.ide.util.ClassFilter;
-import com.intellij.openapi.project.Project;
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 org.jetbrains.annotations.NotNull;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaExceptionBreakpointProperties;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-public class ExceptionBreakpointPropertiesPanel extends BreakpointPropertiesPanel {
+public class ExceptionBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPanel<XBreakpoint<JavaExceptionBreakpointProperties>> {
private JCheckBox myNotifyCaughtCheckBox;
private JCheckBox myNotifyUncaughtCheckBox;
- private ExceptionBreakpoint myExceptionBreakpoint;
+ //private ExceptionBreakpoint myExceptionBreakpoint;
- public ExceptionBreakpointPropertiesPanel(Project project, boolean compact) {
- super(project, ExceptionBreakpoint.CATEGORY, compact);
- }
-
- protected ClassFilter createClassConditionFilter() {
- return null;
- }
+ //public ExceptionBreakpointPropertiesPanel(Project project, boolean compact) {
+ // super(project, ExceptionBreakpoint.CATEGORY, compact);
+ //}
- protected JComponent createSpecialBox() {
+ //protected ClassFilter createClassConditionFilter() {
+ // return null;
+ //}
+ @NotNull
+ @Override
+ public JComponent getComponent() {
myNotifyCaughtCheckBox = new JCheckBox(DebuggerBundle.message("label.exception.breakpoint.properties.panel.caught.exception"));
myNotifyUncaughtCheckBox = new JCheckBox(DebuggerBundle.message("label.exception.breakpoint.properties.panel.uncaught.exception"));
DialogUtil.registerMnemonic(myNotifyCaughtCheckBox);
@@ -91,25 +94,20 @@ public class ExceptionBreakpointPropertiesPanel extends BreakpointPropertiesPane
return _panel;
}
- protected void updateCheckboxes() {
- super.updateCheckboxes();
- myPassCountCheckbox.setEnabled(!(myExceptionBreakpoint instanceof AnyExceptionBreakpoint));
- }
-
- public void initFrom(Breakpoint breakpoint, boolean moreOptionsVisible) {
- ExceptionBreakpoint exceptionBreakpoint = (ExceptionBreakpoint)breakpoint;
- myExceptionBreakpoint = exceptionBreakpoint;
- super.initFrom(breakpoint, moreOptionsVisible);
+ //protected void updateCheckboxes() {
+ // super.updateCheckboxes();
+ // myPassCountCheckbox.setEnabled(!(myExceptionBreakpoint instanceof AnyExceptionBreakpoint));
+ //}
- myNotifyCaughtCheckBox.setSelected(exceptionBreakpoint.NOTIFY_CAUGHT);
- myNotifyUncaughtCheckBox.setSelected(exceptionBreakpoint.NOTIFY_UNCAUGHT);
+ @Override
+ public void loadFrom(@NotNull XBreakpoint<JavaExceptionBreakpointProperties> breakpoint) {
+ myNotifyCaughtCheckBox.setSelected(breakpoint.getProperties().NOTIFY_CAUGHT);
+ myNotifyUncaughtCheckBox.setSelected(breakpoint.getProperties().NOTIFY_UNCAUGHT);
}
- public void saveTo(Breakpoint breakpoint) {
- ExceptionBreakpoint exceptionBreakpoint = (ExceptionBreakpoint)breakpoint;
- exceptionBreakpoint.NOTIFY_CAUGHT = myNotifyCaughtCheckBox.isSelected();
- exceptionBreakpoint.NOTIFY_UNCAUGHT = myNotifyUncaughtCheckBox.isSelected();
-
- super.saveTo(breakpoint);
+ @Override
+ public void saveTo(@NotNull XBreakpoint<JavaExceptionBreakpointProperties> breakpoint) {
+ breakpoint.getProperties().NOTIFY_CAUGHT = myNotifyCaughtCheckBox.isSelected();
+ breakpoint.getProperties().NOTIFY_UNCAUGHT = myNotifyUncaughtCheckBox.isSelected();
}
} \ No newline at end of file
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java
index 365ae242b36d..aa3a29511a2f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpoint.java
@@ -33,19 +33,17 @@ import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizerUtil;
import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.WriteExternalException;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Processor;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.xdebugger.XDebuggerUtil;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.sun.jdi.*;
import com.sun.jdi.event.AccessWatchpointEvent;
import com.sun.jdi.event.LocatableEvent;
@@ -55,26 +53,23 @@ import com.sun.jdi.request.ModificationWatchpointRequest;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaFieldBreakpointProperties;
import javax.swing.*;
-import java.util.List;
-public class FieldBreakpoint extends BreakpointWithHighlighter {
+public class FieldBreakpoint extends BreakpointWithHighlighter<JavaFieldBreakpointProperties> {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.FieldBreakpoint");
- public boolean WATCH_MODIFICATION = true;
- public boolean WATCH_ACCESS = false;
private boolean myIsStatic;
- private String myFieldName;
@NonNls public static final Key<FieldBreakpoint> CATEGORY = BreakpointCategory.lookup("field_breakpoints");
- protected FieldBreakpoint(Project project) {
- super(project);
+ protected FieldBreakpoint(Project project, XBreakpoint breakpoint) {
+ super(project, breakpoint);
}
- private FieldBreakpoint(Project project, RangeHighlighter highlighter, @NotNull String fieldName) {
- super(project, highlighter);
- myFieldName = fieldName;
+ private FieldBreakpoint(Project project, @NotNull String fieldName, XBreakpoint breakpoint) {
+ super(project, breakpoint);
+ setFieldName(fieldName);
}
public boolean isStatic() {
@@ -82,10 +77,9 @@ public class FieldBreakpoint extends BreakpointWithHighlighter {
}
public String getFieldName() {
- return myFieldName;
+ return getProperties().myFieldName;
}
-
@Override
protected Icon getDisabledIcon(boolean isMuted) {
final Breakpoint master = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().findMasterBreakpoint(this);
@@ -128,7 +122,7 @@ public class FieldBreakpoint extends BreakpointWithHighlighter {
@Override
public PsiField compute() {
final PsiClass psiClass = getPsiClassAt(sourcePosition);
- return psiClass != null ? psiClass.findFieldByName(myFieldName, true) : null;
+ return psiClass != null ? psiClass.findFieldByName(getFieldName(), true) : null;
}
});
if (field != null) {
@@ -142,11 +136,15 @@ public class FieldBreakpoint extends BreakpointWithHighlighter {
super.reload(psiFile);
PsiField field = PositionUtil.getPsiElementAt(getProject(), PsiField.class, getSourcePosition());
if(field != null) {
- myFieldName = field.getName();
+ setFieldName(field.getName());
+ PsiClass psiClass = field.getContainingClass();
+ if (psiClass != null) {
+ getProperties().myClassName = psiClass.getQualifiedName();
+ }
myIsStatic = field.hasModifierProperty(PsiModifier.STATIC);
}
if (myIsStatic) {
- INSTANCE_FILTERS_ENABLED = false;
+ setInstanceFiltersEnabled(false);
}
}
@@ -181,20 +179,21 @@ public class FieldBreakpoint extends BreakpointWithHighlighter {
ReferenceType refType) {
VirtualMachineProxy vm = debugProcess.getVirtualMachineProxy();
try {
- Field field = refType.fieldByName(myFieldName);
+ Field field = refType.fieldByName(getFieldName());
if (field == null) {
- debugProcess.getRequestsManager().setInvalid(this, DebuggerBundle.message("error.invalid.breakpoint.missing.field.in.class", myFieldName, refType.name()));
+ debugProcess.getRequestsManager().setInvalid(this, DebuggerBundle.message("error.invalid.breakpoint.missing.field.in.class",
+ getFieldName(), refType.name()));
return;
}
RequestManagerImpl manager = debugProcess.getRequestsManager();
- if (WATCH_MODIFICATION && vm.canWatchFieldModification()) {
+ if (isWatchModification() && vm.canWatchFieldModification()) {
ModificationWatchpointRequest request = manager.createModificationWatchpointRequest(this, field);
debugProcess.getRequestsManager().enableRequest(request);
if (LOG.isDebugEnabled()) {
LOG.debug("Modification request added");
}
}
- if (WATCH_ACCESS && vm.canWatchFieldAccess()) {
+ if (isWatchAccess() && vm.canWatchFieldAccess()) {
AccessWatchpointRequest request = manager.createAccessWatchpointRequest(this, field);
debugProcess.getRequestsManager().enableRequest(request);
if (LOG.isDebugEnabled()) {
@@ -284,11 +283,11 @@ public class FieldBreakpoint extends BreakpointWithHighlighter {
return DebuggerBundle.message("status.breakpoint.invalid");
}
final String className = getClassName();
- return className != null && !className.isEmpty() ? className + "." + myFieldName : myFieldName;
+ return className != null && !className.isEmpty() ? className + "." + getFieldName() : getFieldName();
}
- public static FieldBreakpoint create(@NotNull Project project, @NotNull Document document, int lineIndex, String fieldName) {
- FieldBreakpoint breakpoint = new FieldBreakpoint(project, createHighlighter(project, document, lineIndex), fieldName);
+ public static FieldBreakpoint create(@NotNull Project project, String fieldName, XBreakpoint xBreakpoint) {
+ FieldBreakpoint breakpoint = new FieldBreakpoint(project, fieldName, xBreakpoint);
return (FieldBreakpoint)breakpoint.init();
}
@@ -308,39 +307,39 @@ public class FieldBreakpoint extends BreakpointWithHighlighter {
return field == getPsiField();
}
- protected static FieldBreakpoint create(@NotNull Project project, @NotNull Field field, ObjectReference object) {
- String fieldName = field.name();
- int line = 0;
- Document document = null;
- try {
- List locations = field.declaringType().allLineLocations();
- if(!locations.isEmpty()) {
- Location location = (Location)locations.get(0);
- line = location.lineNumber();
- VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(location.sourcePath());
- if(file != null) {
- PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
- if(psiFile != null) {
- document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
- }
- }
- }
- }
- catch (AbsentInformationException e) {
- LOG.debug(e);
- }
- catch (InternalError e) {
- LOG.debug(e);
- }
-
- if(document == null) return null;
-
- FieldBreakpoint fieldBreakpoint = new FieldBreakpoint(project, createHighlighter(project, document, line), fieldName);
- if (!fieldBreakpoint.isStatic()) {
- fieldBreakpoint.addInstanceFilter(object.uniqueID());
- }
- return (FieldBreakpoint)fieldBreakpoint.init();
- }
+ //protected static FieldBreakpoint create(@NotNull Project project, @NotNull Field field, ObjectReference object, XBreakpoint xBreakpoint) {
+ // String fieldName = field.name();
+ // int line = 0;
+ // Document document = null;
+ // try {
+ // List locations = field.declaringType().allLineLocations();
+ // if(!locations.isEmpty()) {
+ // Location location = (Location)locations.get(0);
+ // line = location.lineNumber();
+ // VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(location.sourcePath());
+ // if(file != null) {
+ // PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
+ // if(psiFile != null) {
+ // document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
+ // }
+ // }
+ // }
+ // }
+ // catch (AbsentInformationException e) {
+ // LOG.debug(e);
+ // }
+ // catch (InternalError e) {
+ // LOG.debug(e);
+ // }
+ //
+ // if(document == null) return null;
+ //
+ // FieldBreakpoint fieldBreakpoint = new FieldBreakpoint(project, createHighlighter(project, document, line), fieldName, xBreakpoint);
+ // if (!fieldBreakpoint.isStatic()) {
+ // fieldBreakpoint.addInstanceFilter(object.uniqueID());
+ // }
+ // return (FieldBreakpoint)fieldBreakpoint.init();
+ //}
public static PsiField findField(Project project, Document document, int offset) {
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
@@ -373,21 +372,41 @@ public class FieldBreakpoint extends BreakpointWithHighlighter {
public void readExternal(@NotNull Element breakpointNode) throws InvalidDataException {
super.readExternal(breakpointNode);
//noinspection HardCodedStringLiteral
- myFieldName = breakpointNode.getAttributeValue("field_name");
- if(myFieldName == null) {
+ setFieldName(breakpointNode.getAttributeValue("field_name"));
+ if(getFieldName() == null) {
throw new InvalidDataException("No field name for field breakpoint");
}
+ try {
+ getProperties().WATCH_MODIFICATION = Boolean.valueOf(JDOMExternalizerUtil.readField(breakpointNode, "WATCH_MODIFICATION"));
+ } catch (Exception e) {
+ }
+ try {
+ getProperties().WATCH_ACCESS = Boolean.valueOf(JDOMExternalizerUtil.readField(breakpointNode, "WATCH_ACCESS"));
+ } catch (Exception e) {
+ }
}
-
- @Override
- @SuppressWarnings({"HardCodedStringLiteral"})
- public void writeExternal(@NotNull Element parentNode) throws WriteExternalException {
- super.writeExternal(parentNode);
- parentNode.setAttribute("field_name", getFieldName());
- }
+ //
+ //@Override
+ //@SuppressWarnings({"HardCodedStringLiteral"})
+ //public void writeExternal(@NotNull Element parentNode) throws WriteExternalException {
+ // super.writeExternal(parentNode);
+ // parentNode.setAttribute("field_name", getFieldName());
+ //}
@Override
public PsiElement getEvaluationElement() {
return getPsiClass();
}
+
+ private boolean isWatchModification() {
+ return getProperties().WATCH_MODIFICATION;
+ }
+
+ private boolean isWatchAccess() {
+ return getProperties().WATCH_ACCESS;
+ }
+
+ private void setFieldName(String fieldName) {
+ getProperties().myFieldName = fieldName;
+ }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java
deleted file mode 100644
index 1bdef0c862e7..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointFactory.java
+++ /dev/null
@@ -1,127 +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.ui.breakpoints;
-
-import com.intellij.CommonBundle;
-import com.intellij.debugger.DebuggerBundle;
-import com.intellij.debugger.DebuggerManagerEx;
-import com.intellij.debugger.HelpID;
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.Ref;
-import com.intellij.psi.*;
-import com.intellij.psi.search.GlobalSearchScope;
-import org.jdom.Element;
-
-import javax.swing.*;
-
-/**
- * @author Eugene Zhuravlev
- * Date: Apr 26, 2005
- */
-public class FieldBreakpointFactory extends BreakpointFactory{
- public Breakpoint createBreakpoint(Project project, final Element element) {
- return new FieldBreakpoint(project);
- }
-
- public Icon getIcon() {
- return AllIcons.Debugger.Db_field_breakpoint;
- }
-
- public Icon getDisabledIcon() {
- return AllIcons.Debugger.Db_disabled_field_breakpoint;
- }
-
- @Override
- protected String getHelpID() {
- return HelpID.FIELD_WATCHPOINTS;
- }
-
- @Override
- public String getDisplayName() {
- return DebuggerBundle.message("field.watchpoints.tab.title");
- }
-
- @Override
- public BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact) {
- return new FieldBreakpointPropertiesPanel(project, compact);
- }
-
- public Key<FieldBreakpoint> getBreakpointCategory() {
- return FieldBreakpoint.CATEGORY;
- }
-
- @Override
- public Breakpoint addBreakpoint(final Project project) {
- final Ref<Breakpoint> result = Ref.create(null);
- AddFieldBreakpointDialog dialog = new AddFieldBreakpointDialog(project) {
- protected boolean validateData() {
- String className = getClassName();
- if (className.length() == 0) {
- Messages.showMessageDialog(project, DebuggerBundle.message("error.field.breakpoint.class.name.not.specified"),
- DebuggerBundle.message("add.field.breakpoint.dialog.title"), Messages.getErrorIcon());
- return false;
- }
- String fieldName = getFieldName();
- if (fieldName.length() == 0) {
- Messages.showMessageDialog(project, DebuggerBundle.message("error.field.breakpoint.field.name.not.specified"),
- DebuggerBundle.message("add.field.breakpoint.dialog.title"), Messages.getErrorIcon());
- return false;
- }
- PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project));
- if (psiClass != null) {
- PsiFile psiFile = psiClass.getContainingFile();
- Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
- if(document != null) {
- PsiField field = psiClass.findFieldByName(fieldName, true);
- if(field != null) {
- int line = document.getLineNumber(field.getTextOffset());
- FieldBreakpoint fieldBreakpoint = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().addFieldBreakpoint(document, line, fieldName);
- if (fieldBreakpoint != null) {
- result.set(fieldBreakpoint);
- return true;
- }
- }
- else {
- Messages.showMessageDialog(project,
- DebuggerBundle.message("error.field.breakpoint.field.not.found", className, fieldName, fieldName),
- CommonBundle.getErrorTitle(),
- Messages.getErrorIcon()
- );
- }
- }
- } else {
- Messages.showMessageDialog(project,
- DebuggerBundle.message("error.field.breakpoint.class.sources.not.found", className, fieldName, className),
- CommonBundle.getErrorTitle(),
- Messages.getErrorIcon()
- );
- }
- return false;
- }
- };
- dialog.show();
- return result.get();
- }
-
- @Override
- public boolean canAddBreakpoints() {
- return true;
- }
-}
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 bec12645dd80..4d0bec2e165b 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
@@ -21,24 +21,30 @@
package com.intellij.debugger.ui.breakpoints;
import com.intellij.debugger.DebuggerBundle;
-import com.intellij.openapi.project.Project;
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 org.jetbrains.annotations.NotNull;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaFieldBreakpointProperties;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-public class FieldBreakpointPropertiesPanel extends BreakpointPropertiesPanel {
+public class FieldBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPanel<XLineBreakpoint<JavaFieldBreakpointProperties>> {
private JCheckBox myWatchAccessCheckBox;
private JCheckBox myWatchModificationCheckBox;
- public FieldBreakpointPropertiesPanel(final Project project, boolean compact) {
- super(project, FieldBreakpoint.CATEGORY, compact);
- }
+ //public FieldBreakpointPropertiesPanel(final Project project, boolean compact) {
+ // super(project, FieldBreakpoint.CATEGORY, compact);
+ //}
+
- protected JComponent createSpecialBox() {
+ @NotNull
+ @Override
+ public JComponent getComponent() {
JPanel _panel;
JPanel _panel0;
myWatchAccessCheckBox = new JCheckBox(DebuggerBundle.message("label.filed.breakpoint.properties.panel.field.access"));
@@ -86,20 +92,15 @@ public class FieldBreakpointPropertiesPanel extends BreakpointPropertiesPanel {
return _panel;
}
- public void initFrom(Breakpoint breakpoint, boolean moreOptionsVisible) {
- super.initFrom(breakpoint, moreOptionsVisible);
- FieldBreakpoint fieldBreakpoint = (FieldBreakpoint)breakpoint;
-
- myWatchAccessCheckBox.setSelected(fieldBreakpoint.WATCH_ACCESS);
- myWatchModificationCheckBox.setSelected(fieldBreakpoint.WATCH_MODIFICATION);
+ @Override
+ public void loadFrom(@NotNull XLineBreakpoint<JavaFieldBreakpointProperties> breakpoint) {
+ myWatchAccessCheckBox.setSelected(breakpoint.getProperties().WATCH_ACCESS);
+ myWatchModificationCheckBox.setSelected(breakpoint.getProperties().WATCH_MODIFICATION);
}
- public void saveTo(Breakpoint breakpoint) {
- FieldBreakpoint fieldBreakpoint = (FieldBreakpoint)breakpoint;
-
- fieldBreakpoint.WATCH_ACCESS = myWatchAccessCheckBox.isSelected();
- fieldBreakpoint.WATCH_MODIFICATION = myWatchModificationCheckBox.isSelected();
-
- super.saveTo(breakpoint);
+ @Override
+ public void saveTo(@NotNull XLineBreakpoint<JavaFieldBreakpointProperties> breakpoint) {
+ breakpoint.getProperties().WATCH_ACCESS = myWatchAccessCheckBox.isSelected();
+ breakpoint.getProperties().WATCH_MODIFICATION = myWatchModificationCheckBox.isSelected();
}
} \ No newline at end of file
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java
index 8aa57bd351d8..6a628f189bc5 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestor.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,250 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/**
- * class FilteredRequestor
- * @author Jeka
- */
package com.intellij.debugger.ui.breakpoints;
-import com.intellij.debugger.*;
-import com.intellij.debugger.engine.ContextUtil;
-import com.intellij.debugger.engine.DebugProcessImpl;
-import com.intellij.debugger.engine.evaluation.*;
-import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl;
-import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
+import com.intellij.debugger.InstanceFilter;
import com.intellij.debugger.engine.requests.LocatableEventRequestor;
-import com.intellij.debugger.impl.DebuggerUtilsEx;
-import com.intellij.debugger.settings.DebuggerSettings;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.*;
-import com.intellij.psi.PsiElement;
import com.intellij.ui.classFilter.ClassFilter;
-import com.sun.jdi.BooleanValue;
-import com.sun.jdi.ObjectReference;
-import com.sun.jdi.VMDisconnectedException;
-import com.sun.jdi.Value;
-import com.sun.jdi.event.LocatableEvent;
-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.List;
-
-public abstract class FilteredRequestor implements LocatableEventRequestor, JDOMExternalizable {
-
- public String SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL;
- public boolean SUSPEND = true;
-
- public boolean COUNT_FILTER_ENABLED = false;
- public int COUNT_FILTER = 0;
-
- public boolean CONDITION_ENABLED = false;
- private TextWithImports myCondition;
-
- public boolean CLASS_FILTERS_ENABLED = false;
- private ClassFilter[] myClassFilters = ClassFilter.EMPTY_ARRAY;
- private ClassFilter[] myClassExclusionFilters = ClassFilter.EMPTY_ARRAY;
-
- public boolean INSTANCE_FILTERS_ENABLED = false;
- private InstanceFilter[] myInstanceFilters = InstanceFilter.EMPTY_ARRAY;
-
- @NonNls private static final String FILTER_OPTION_NAME = "filter";
- @NonNls private static final String EXCLUSION_FILTER_OPTION_NAME = "exclusion_filter";
- @NonNls private static final String INSTANCE_ID_OPTION_NAME = "instance_id";
- @NonNls private static final String CONDITION_OPTION_NAME = "CONDITION";
- protected final Project myProject;
-
- public FilteredRequestor(@NotNull Project project) {
- myProject = project;
- myCondition = new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "");
- }
-
- public InstanceFilter[] getInstanceFilters() {
- return myInstanceFilters;
- }
-
- public void setInstanceFilters(InstanceFilter[] instanceFilters) {
- myInstanceFilters = instanceFilters != null? instanceFilters : InstanceFilter.EMPTY_ARRAY;
- }
-
- public String getSuspendPolicy() {
- return SUSPEND? SUSPEND_POLICY : DebuggerSettings.SUSPEND_NONE;
- }
-
- /**
- * @return true if the ID was added or false otherwise
- */
- private boolean hasObjectID(long id) {
- for (InstanceFilter instanceFilter : myInstanceFilters) {
- if (instanceFilter.getId() == id) {
- return true;
- }
- }
- return false;
- }
-
- protected void addInstanceFilter(long l) {
- final InstanceFilter[] filters = new InstanceFilter[myInstanceFilters.length + 1];
- System.arraycopy(myInstanceFilters, 0, filters, 0, myInstanceFilters.length);
- filters[myInstanceFilters.length] = InstanceFilter.create(String.valueOf(l));
- myInstanceFilters = filters;
- }
- public final ClassFilter[] getClassFilters() {
- return myClassFilters;
- }
-
- public final void setClassFilters(ClassFilter[] classFilters) {
- myClassFilters = classFilters != null? classFilters : ClassFilter.EMPTY_ARRAY;
- }
-
- public ClassFilter[] getClassExclusionFilters() {
- return myClassExclusionFilters;
- }
-
- public void setClassExclusionFilters(ClassFilter[] classExclusionFilters) {
- myClassExclusionFilters = classExclusionFilters != null? classExclusionFilters : ClassFilter.EMPTY_ARRAY;
- }
-
- public void readExternal(Element parentNode) throws InvalidDataException {
- DefaultJDOMExternalizer.readExternal(this, parentNode);
- if (DebuggerSettings.SUSPEND_NONE.equals(SUSPEND_POLICY)) { // compatibility with older format
- SUSPEND = false;
- SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL;
- }
- String condition = JDOMExternalizerUtil.readField(parentNode, CONDITION_OPTION_NAME);
- if (condition != null) {
- setCondition(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, condition));
- }
-
- myClassFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren(FILTER_OPTION_NAME));
- myClassExclusionFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren(EXCLUSION_FILTER_OPTION_NAME));
-
- final ClassFilter [] instanceFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren(INSTANCE_ID_OPTION_NAME));
- final List<InstanceFilter> iFilters = new ArrayList<InstanceFilter>(instanceFilters.length);
-
- for (ClassFilter instanceFilter : instanceFilters) {
- try {
- iFilters.add(InstanceFilter.create(instanceFilter));
- }
- catch (Exception e) {
- }
- }
- myInstanceFilters = iFilters.isEmpty() ? InstanceFilter.EMPTY_ARRAY : iFilters.toArray(new InstanceFilter[iFilters.size()]);
- }
-
- public void writeExternal(Element parentNode) throws WriteExternalException {
- DefaultJDOMExternalizer.writeExternal(this, parentNode);
- JDOMExternalizerUtil.writeField(parentNode, CONDITION_OPTION_NAME, getCondition().toExternalForm());
- DebuggerUtilsEx.writeFilters(parentNode, FILTER_OPTION_NAME, myClassFilters);
- DebuggerUtilsEx.writeFilters(parentNode, EXCLUSION_FILTER_OPTION_NAME, myClassExclusionFilters);
- DebuggerUtilsEx.writeFilters(parentNode, INSTANCE_ID_OPTION_NAME, InstanceFilter.createClassFilters(myInstanceFilters));
- }
-
- public boolean evaluateCondition(final EvaluationContextImpl context, LocatableEvent event) throws EvaluateException {
- if(COUNT_FILTER_ENABLED) {
- final DebugProcessImpl debugProcess = context.getDebugProcess();
- debugProcess.getVirtualMachineProxy().suspend();
- debugProcess.getRequestsManager().deleteRequest(this);
- ((Breakpoint)this).createRequest(debugProcess);
- debugProcess.getVirtualMachineProxy().resume();
- }
- if (INSTANCE_FILTERS_ENABLED) {
- Value value = context.getThisObject();
- if (value != null) { // non-static
- ObjectReference reference = (ObjectReference)value;
- if(!hasObjectID(reference.uniqueID())) {
- return false;
- }
- }
- }
-
- if (CLASS_FILTERS_ENABLED) {
- String typeName = calculateEventClass(context, event);
- if (!typeMatchesClassFilters(typeName)) return false;
- }
-
- if (CONDITION_ENABLED && getCondition() != null && !"".equals(getCondition().getText())) {
- try {
- ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(context.getProject(), new EvaluatingComputable<ExpressionEvaluator>() {
- public ExpressionEvaluator compute() throws EvaluateException {
- final SourcePosition contextSourcePosition = ContextUtil.getSourcePosition(context);
- // IMPORTANT: calculate context psi element basing on the location where the exception
- // has been hit, not on the location where it was set. (For line breakpoints these locations are the same, however,
- // for method, exception and field breakpoints these locations differ)
- PsiElement contextPsiElement = ContextUtil.getContextElement(contextSourcePosition);
- if (contextPsiElement == null) {
- contextPsiElement = getEvaluationElement(); // as a last resort
- }
- return EvaluatorBuilderImpl.build(getCondition(), contextPsiElement, contextSourcePosition);
- }
- });
- final Value value = evaluator.evaluate(context);
- if (!(value instanceof BooleanValue)) {
- throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.boolean.expected"));
- }
- if(!((BooleanValue)value).booleanValue()) {
- return false;
- }
- }
- catch (EvaluateException ex) {
- if(ex.getCause() instanceof VMDisconnectedException) {
- return false;
- }
- throw EvaluateExceptionUtil.createEvaluateException(
- DebuggerBundle.message("error.failed.evaluating.breakpoint.condition", getCondition(), ex.getMessage())
- );
- }
- return true;
- }
-
- return true;
- }
-
- protected String calculateEventClass(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException {
- return event.location().declaringType().name();
- }
-
- private boolean typeMatchesClassFilters(@Nullable String typeName) {
- if (typeName == null) {
- return true;
- }
- boolean matches = false, hasEnabled = false;
- for (ClassFilter classFilter : getClassFilters()) {
- if (classFilter.isEnabled()) {
- hasEnabled = true;
- if (classFilter.matches(typeName)) {
- matches = true;
- break;
- }
- }
- }
- if(hasEnabled && !matches) {
- return false;
- }
- for (ClassFilter classFilter : getClassExclusionFilters()) {
- if (classFilter.isEnabled() && classFilter.matches(typeName)) {
- return false;
- }
- }
- return true;
- }
-
- public abstract PsiElement getEvaluationElement();
+/**
+ * @author egor
+ */
+public interface FilteredRequestor extends LocatableEventRequestor {
+ String getSuspendPolicy();
- public TextWithImports getCondition() {
- return myCondition;
- }
+ boolean isInstanceFiltersEnabled();
+ InstanceFilter[] getInstanceFilters();
- public void setCondition(TextWithImports condition) {
- myCondition = condition;
- }
+ boolean isCountFilterEnabled();
+ int getCountFilter();
- public Project getProject() {
- return myProject;
- }
+ boolean isClassFiltersEnabled();
+ ClassFilter[] getClassFilters();
+ ClassFilter[] getClassExclusionFilters();
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestorImpl.java
new file mode 100644
index 000000000000..496292881354
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestorImpl.java
@@ -0,0 +1,243 @@
+/*
+ * 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.
+ */
+
+/**
+ * class FilteredRequestorImpl
+ * @author Jeka
+ */
+package com.intellij.debugger.ui.breakpoints;
+
+import com.intellij.debugger.InstanceFilter;
+import com.intellij.debugger.engine.evaluation.*;
+import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
+import com.intellij.debugger.impl.DebuggerUtilsEx;
+import com.intellij.debugger.settings.DebuggerSettings;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.*;
+import com.intellij.psi.PsiElement;
+import com.intellij.ui.classFilter.ClassFilter;
+import com.sun.jdi.event.LocatableEvent;
+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.List;
+
+/*
+ * Not used any more, since move to xBreakpoints
+ */
+public class FilteredRequestorImpl implements JDOMExternalizable, FilteredRequestor {
+
+ public String SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL;
+ public boolean SUSPEND = true;
+
+ public boolean COUNT_FILTER_ENABLED = false;
+ public int COUNT_FILTER = 0;
+
+ public boolean CONDITION_ENABLED = false;
+ private TextWithImports myCondition;
+
+ public boolean CLASS_FILTERS_ENABLED = false;
+ private ClassFilter[] myClassFilters = ClassFilter.EMPTY_ARRAY;
+ private ClassFilter[] myClassExclusionFilters = ClassFilter.EMPTY_ARRAY;
+
+ public boolean INSTANCE_FILTERS_ENABLED = false;
+ private InstanceFilter[] myInstanceFilters = InstanceFilter.EMPTY_ARRAY;
+
+ @NonNls private static final String FILTER_OPTION_NAME = "filter";
+ @NonNls private static final String EXCLUSION_FILTER_OPTION_NAME = "exclusion_filter";
+ @NonNls private static final String INSTANCE_ID_OPTION_NAME = "instance_id";
+ @NonNls private static final String CONDITION_OPTION_NAME = "CONDITION";
+ protected final Project myProject;
+
+ public FilteredRequestorImpl(@NotNull Project project) {
+ myProject = project;
+ myCondition = new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "");
+ }
+
+ public InstanceFilter[] getInstanceFilters() {
+ return myInstanceFilters;
+ }
+
+ public void setInstanceFilters(InstanceFilter[] instanceFilters) {
+ myInstanceFilters = instanceFilters != null? instanceFilters : InstanceFilter.EMPTY_ARRAY;
+ }
+
+ public String getSuspendPolicy() {
+ return SUSPEND? SUSPEND_POLICY : DebuggerSettings.SUSPEND_NONE;
+ }
+
+ /**
+ * @return true if the ID was added or false otherwise
+ */
+ private boolean hasObjectID(long id) {
+ for (InstanceFilter instanceFilter : myInstanceFilters) {
+ if (instanceFilter.getId() == id) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected void addInstanceFilter(long l) {
+ final InstanceFilter[] filters = new InstanceFilter[myInstanceFilters.length + 1];
+ System.arraycopy(myInstanceFilters, 0, filters, 0, myInstanceFilters.length);
+ filters[myInstanceFilters.length] = InstanceFilter.create(String.valueOf(l));
+ myInstanceFilters = filters;
+ }
+
+ public final ClassFilter[] getClassFilters() {
+ return myClassFilters;
+ }
+
+ public final void setClassFilters(ClassFilter[] classFilters) {
+ myClassFilters = classFilters != null? classFilters : ClassFilter.EMPTY_ARRAY;
+ }
+
+ public ClassFilter[] getClassExclusionFilters() {
+ return myClassExclusionFilters;
+ }
+
+ public void setClassExclusionFilters(ClassFilter[] classExclusionFilters) {
+ myClassExclusionFilters = classExclusionFilters != null? classExclusionFilters : ClassFilter.EMPTY_ARRAY;
+ }
+
+ public void readTo(Element parentNode, Breakpoint breakpoint) throws InvalidDataException {
+ readExternal(parentNode);
+ if (SUSPEND) {
+ breakpoint.setSuspendPolicy(SUSPEND_POLICY);
+ }
+ else {
+ breakpoint.setSuspendPolicy(DebuggerSettings.SUSPEND_NONE);
+ }
+
+ breakpoint.setCountFilterEnabled(COUNT_FILTER_ENABLED);
+ breakpoint.setCountFilter(COUNT_FILTER);
+
+ breakpoint.setCondition(CONDITION_ENABLED ? myCondition : null);
+
+ breakpoint.setClassFiltersEnabled(CLASS_FILTERS_ENABLED);
+ breakpoint.setClassFilters(getClassFilters());
+ breakpoint.setClassExclusionFilters(getClassExclusionFilters());
+
+ breakpoint.setInstanceFiltersEnabled(INSTANCE_FILTERS_ENABLED);
+ breakpoint.setInstanceFilters(getInstanceFilters());
+ }
+
+ public void readExternal(Element parentNode) throws InvalidDataException {
+ DefaultJDOMExternalizer.readExternal(this, parentNode);
+ if (DebuggerSettings.SUSPEND_NONE.equals(SUSPEND_POLICY)) { // compatibility with older format
+ SUSPEND = false;
+ SUSPEND_POLICY = DebuggerSettings.SUSPEND_ALL;
+ }
+ String condition = JDOMExternalizerUtil.readField(parentNode, CONDITION_OPTION_NAME);
+ if (condition != null) {
+ setCondition(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, condition));
+ }
+
+ myClassFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren(FILTER_OPTION_NAME));
+ myClassExclusionFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren(EXCLUSION_FILTER_OPTION_NAME));
+
+ final ClassFilter [] instanceFilters = DebuggerUtilsEx.readFilters(parentNode.getChildren(INSTANCE_ID_OPTION_NAME));
+ final List<InstanceFilter> iFilters = new ArrayList<InstanceFilter>(instanceFilters.length);
+
+ for (ClassFilter instanceFilter : instanceFilters) {
+ try {
+ iFilters.add(InstanceFilter.create(instanceFilter));
+ }
+ catch (Exception e) {
+ }
+ }
+ myInstanceFilters = iFilters.isEmpty() ? InstanceFilter.EMPTY_ARRAY : iFilters.toArray(new InstanceFilter[iFilters.size()]);
+ }
+
+ public void writeExternal(Element parentNode) throws WriteExternalException {
+ DefaultJDOMExternalizer.writeExternal(this, parentNode);
+ JDOMExternalizerUtil.writeField(parentNode, CONDITION_OPTION_NAME, getCondition().toExternalForm());
+ DebuggerUtilsEx.writeFilters(parentNode, FILTER_OPTION_NAME, myClassFilters);
+ DebuggerUtilsEx.writeFilters(parentNode, EXCLUSION_FILTER_OPTION_NAME, myClassExclusionFilters);
+ DebuggerUtilsEx.writeFilters(parentNode, INSTANCE_ID_OPTION_NAME, InstanceFilter.createClassFilters(myInstanceFilters));
+ }
+
+ protected String calculateEventClass(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException {
+ return event.location().declaringType().name();
+ }
+
+ private boolean typeMatchesClassFilters(@Nullable String typeName) {
+ if (typeName == null) {
+ return true;
+ }
+ boolean matches = false, hasEnabled = false;
+ for (ClassFilter classFilter : getClassFilters()) {
+ if (classFilter.isEnabled()) {
+ hasEnabled = true;
+ if (classFilter.matches(typeName)) {
+ matches = true;
+ break;
+ }
+ }
+ }
+ if(hasEnabled && !matches) {
+ return false;
+ }
+ for (ClassFilter classFilter : getClassExclusionFilters()) {
+ if (classFilter.isEnabled() && classFilter.matches(typeName)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public PsiElement getEvaluationElement() {
+ return null;
+ }
+
+ public TextWithImports getCondition() {
+ return myCondition;
+ }
+
+ public void setCondition(TextWithImports condition) {
+ myCondition = condition;
+ }
+
+ public Project getProject() {
+ return myProject;
+ }
+
+ public boolean isCountFilterEnabled() {
+ return COUNT_FILTER_ENABLED;
+ }
+
+ public int getCountFilter() {
+ return COUNT_FILTER;
+ }
+
+ public boolean isClassFiltersEnabled() {
+ return CLASS_FILTERS_ENABLED;
+ }
+
+ public boolean isInstanceFiltersEnabled() {
+ return INSTANCE_FILTERS_ENABLED;
+ }
+
+ @Override
+ public boolean processLocatableEvent(SuspendContextCommandImpl action, LocatableEvent event)
+ throws EventProcessingException {
+ return false;
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
deleted file mode 100644
index ec3577cbae0a..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
+++ /dev/null
@@ -1,184 +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.debugger.ui.breakpoints;
-
-import com.intellij.debugger.DebuggerManagerEx;
-import com.intellij.debugger.SourcePosition;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.SimpleColoredComponent;
-import com.intellij.ui.SimpleTextAttributes;
-import com.intellij.ui.popup.util.DetailView;
-import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-
-class JavaBreakpointItem extends BreakpointItem {
- private final Breakpoint myBreakpoint;
- private BreakpointFactory myBreakpointFactory;
- private BreakpointPropertiesPanel myBreakpointPropertiesPanel;
-
- public JavaBreakpointItem(@Nullable BreakpointFactory breakpointFactory, Breakpoint breakpoint) {
- myBreakpointFactory = breakpointFactory;
- myBreakpoint = breakpoint;
- }
-
- @Override
- public void setupGenericRenderer(SimpleColoredComponent renderer, boolean plainView) {
- if (plainView) {
- renderer.setIcon(myBreakpoint.getIcon());
- }
- renderer.append(plainView ? StringUtil.shortenTextWithEllipsis(myBreakpoint.getShortName(), 60, 0) : myBreakpoint.getDisplayName(),
- isEnabled() ? SimpleTextAttributes.REGULAR_ATTRIBUTES : SimpleTextAttributes.GRAY_ATTRIBUTES);
- }
-
- @Override
- public Icon getIcon() {
- return myBreakpoint.getIcon();
- }
-
- @Override
- public String getDisplayText() {
- return myBreakpoint.getDisplayName();
- }
-
- @Override
- public String speedSearchText() {
- return myBreakpoint.getDisplayName();
- }
-
- @Override
- public String footerText() {
- return myBreakpoint.getDisplayName();
- }
-
- @Override
- protected void doUpdateDetailView(DetailView panel, boolean editorOnly) {
- //saveState();
- if (myBreakpointPropertiesPanel != null) {
- myBreakpointPropertiesPanel.dispose();
- myBreakpointPropertiesPanel = null;
- }
-
- if (!editorOnly) {
- myBreakpointPropertiesPanel = myBreakpointFactory != null ? myBreakpointFactory
- .createBreakpointPropertiesPanel(myBreakpoint.getProject(), false) : null;
-
- if (myBreakpointPropertiesPanel != null) {
- myBreakpointPropertiesPanel.initFrom(myBreakpoint, true);
-
- final JPanel mainPanel = myBreakpointPropertiesPanel.getPanel();
- panel.setPropertiesPanel(mainPanel);
- }
- else {
- panel.setPropertiesPanel(null);
- }
- }
-
- if (myBreakpoint instanceof BreakpointWithHighlighter) {
- SourcePosition sourcePosition = ((BreakpointWithHighlighter)myBreakpoint).getSourcePosition();
- VirtualFile virtualFile = sourcePosition.getFile().getVirtualFile();
- showInEditor(panel, virtualFile, sourcePosition.getLine());
- } else {
- panel.clearEditor();
- }
- if (myBreakpointPropertiesPanel != null) {
- myBreakpointPropertiesPanel.setDetailView(panel);
- }
- }
-
- @Override
- public void navigate(boolean requestFocus) {
- if (myBreakpoint instanceof BreakpointWithHighlighter) {
- ((BreakpointWithHighlighter)myBreakpoint).getSourcePosition().navigate(requestFocus);
- }
- }
-
- @Override
- public boolean canNavigate() {
- return myBreakpoint instanceof BreakpointWithHighlighter && ((BreakpointWithHighlighter)myBreakpoint).getSourcePosition().canNavigate();
- }
-
- @Override
- public boolean canNavigateToSource() {
- return myBreakpoint instanceof BreakpointWithHighlighter &&
- ((BreakpointWithHighlighter)myBreakpoint).getSourcePosition().canNavigateToSource();
- }
-
- @Override
- public boolean allowedToRemove() {
- return myBreakpointFactory != null && myBreakpointFactory.breakpointCanBeRemoved(myBreakpoint);
- }
-
- @Override
- public void removed(Project project) {
- dispose();
- DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().removeBreakpoint(myBreakpoint);
- }
-
- @Override
- public void saveState() {
- if (myBreakpointPropertiesPanel != null) {
- myBreakpointPropertiesPanel.saveTo(myBreakpoint);
- }
- }
-
- @Override
- public Object getBreakpoint() {
- return myBreakpoint;
- }
-
- @Override
- public boolean isEnabled() {
- return myBreakpoint.ENABLED;
- }
-
- @Override
- public void setEnabled(boolean state) {
- myBreakpoint.ENABLED = state;
- myBreakpoint.updateUI();
- DebuggerManagerEx.getInstanceEx(myBreakpoint.getProject()).getBreakpointManager().fireBreakpointChanged(myBreakpoint);
- }
-
- @Override
- public boolean isDefaultBreakpoint() {
- return myBreakpoint.getCategory().equals(ExceptionBreakpoint.CATEGORY);
- }
-
- @Override
- protected void dispose() {
- if (myBreakpointPropertiesPanel != null) {
- myBreakpointPropertiesPanel.dispose();
- myBreakpointPropertiesPanel = null;
- }
- }
-
- @Override
- public int compareTo(@NotNull BreakpointItem breakpointItem) {
- final Object breakpoint = breakpointItem.getBreakpoint();
- if (breakpoint instanceof Breakpoint) {
- return -getIndexOf(myBreakpoint) + getIndexOf((Breakpoint)breakpoint);
- }
- return getDisplayText().compareTo(breakpointItem.getDisplayText());
- }
-
- private int getIndexOf(Breakpoint breakpoint) {
- return DebuggerManagerEx.getInstanceEx(myBreakpoint.getProject()).getBreakpointManager().getBreakpoints().indexOf(breakpoint);
- }
-}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.java
index 802657b44fd9..2776032a2f4f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointPropertiesPanel.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.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,17 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
- * Class LineBreakpointPropertiesPanel
- * @author Jeka
- */
package com.intellij.debugger.ui.breakpoints;
import com.intellij.openapi.project.Project;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties;
-public class LineBreakpointPropertiesPanel extends BreakpointPropertiesPanel {
- public LineBreakpointPropertiesPanel(Project project, boolean compact) {
- super(project, LineBreakpoint.CATEGORY, compact);
- }
-} \ No newline at end of file
+/**
+ * Base class for all Java breakpoint types
+ * @author egor
+ */
+public interface JavaBreakpointType<P extends JavaBreakpointProperties> {
+ Breakpoint createJavaBreakpoint(Project project, XBreakpoint<P> breakpoint);
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java
new file mode 100644
index 000000000000..0bb20d620c2d
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.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.debugger.ui.breakpoints;
+
+import com.intellij.debugger.DebuggerManagerEx;
+import com.intellij.debugger.ui.JavaDebuggerSupport;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiClass;
+import com.intellij.xdebugger.XDebuggerUtil;
+import com.intellij.xdebugger.XSourcePosition;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.XBreakpointType;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.JavaDebuggerEditorsProvider;
+import org.jetbrains.java.debugger.breakpoints.JavaBreakpointFiltersPanel;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties;
+
+/**
+ * Base class for non-line java breakpoint
+ * @author egor
+ */
+public abstract class JavaBreakpointTypeBase<T extends JavaBreakpointProperties> extends XBreakpointType<XBreakpoint<T>, T> {
+ protected JavaBreakpointTypeBase(@NonNls @NotNull String id, @Nls @NotNull String title) {
+ super(id, title, true);
+ }
+
+ @Override
+ public final boolean isAddBreakpointButtonVisible() {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public final XBreakpointCustomPropertiesPanel<XBreakpoint<T>> createCustomRightPropertiesPanel(@NotNull Project project) {
+ return new JavaBreakpointFiltersPanel<T, XBreakpoint<T>>(project);
+ }
+
+ @Nullable
+ @Override
+ public final XDebuggerEditorsProvider getEditorsProvider(@NotNull XBreakpoint<T> breakpoint, @NotNull Project project) {
+ return new JavaDebuggerEditorsProvider();
+ }
+
+ @Nullable
+ @Override
+ public XSourcePosition getSourcePosition(@NotNull XBreakpoint<T> breakpoint) {
+ BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(JavaDebuggerSupport.getCurrentProject()).getBreakpointManager();
+ Breakpoint javaBreakpoint = breakpointManager.findBreakpoint(breakpoint);
+ if (javaBreakpoint != null) {
+ PsiClass aClass = javaBreakpoint.getPsiClass();
+ if (aClass != null && aClass.getContainingFile() != null) {
+ return XDebuggerUtil.getInstance().createPositionByOffset(aClass.getContainingFile().getVirtualFile(), aClass.getTextOffset());
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java
new file mode 100644
index 000000000000..d5d4b714875c
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java
@@ -0,0 +1,138 @@
+/*
+ * 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.ui.breakpoints;
+
+import com.intellij.debugger.DebuggerBundle;
+import com.intellij.debugger.HelpID;
+import com.intellij.debugger.engine.JVMNameUtil;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.TreeClassChooser;
+import com.intellij.ide.util.TreeClassChooserFactory;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassOwner;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.xdebugger.XDebuggerManager;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaExceptionBreakpointProperties;
+
+import javax.swing.*;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Apr 26, 2005
+ */
+public class JavaExceptionBreakpointType extends JavaBreakpointTypeBase<JavaExceptionBreakpointProperties>
+ implements JavaBreakpointType<JavaExceptionBreakpointProperties> {
+ public JavaExceptionBreakpointType() {
+ super("java-exception", DebuggerBundle.message("exception.breakpoints.tab.title"));
+ }
+
+ @NotNull
+ @Override
+ public Icon getEnabledIcon() {
+ return AllIcons.Debugger.Db_exception_breakpoint;
+ }
+
+ @NotNull
+ @Override
+ public Icon getDisabledIcon() {
+ return AllIcons.Debugger.Db_disabled_exception_breakpoint;
+ }
+
+ //@Override
+ protected String getHelpID() {
+ return HelpID.EXCEPTION_BREAKPOINTS;
+ }
+
+ //@Override
+ public String getDisplayName() {
+ return DebuggerBundle.message("exception.breakpoints.tab.title");
+ }
+
+ @Override
+ public String getDisplayText(XBreakpoint<JavaExceptionBreakpointProperties> breakpoint) {
+ String name = breakpoint.getProperties().myQualifiedName;
+ if (name != null) {
+ return DebuggerBundle.message("breakpoint.exception.breakpoint.display.name", name);
+ }
+ else {
+ return DebuggerBundle.message("breakpoint.any.exception.display.name");
+ }
+ }
+
+ @Nullable
+ @Override
+ public JavaExceptionBreakpointProperties createProperties() {
+ return new JavaExceptionBreakpointProperties();
+ }
+
+ @Nullable
+ @Override
+ public XBreakpointCustomPropertiesPanel<XBreakpoint<JavaExceptionBreakpointProperties>> createCustomPropertiesPanel() {
+ return new ExceptionBreakpointPropertiesPanel();
+ }
+
+ @Nullable
+ @Override
+ public XBreakpoint<JavaExceptionBreakpointProperties> createDefaultBreakpoint(@NotNull XBreakpointCreator<JavaExceptionBreakpointProperties> creator) {
+ return creator.createBreakpoint(new JavaExceptionBreakpointProperties());
+ }
+
+ //public Key<ExceptionBreakpoint> getBreakpointCategory() {
+ // return ExceptionBreakpoint.CATEGORY;
+ //}
+
+ @Nullable
+ @Override
+ public XBreakpoint<JavaExceptionBreakpointProperties> addBreakpoint(final Project project, JComponent parentComponent) {
+ final PsiClass throwableClass =
+ JavaPsiFacade.getInstance(project).findClass("java.lang.Throwable", GlobalSearchScope.allScope(project));
+ TreeClassChooser chooser = TreeClassChooserFactory.getInstance(project)
+ .createInheritanceClassChooser(DebuggerBundle.message("add.exception.breakpoint.classchooser.title"),
+ GlobalSearchScope.allScope(project), throwableClass, true, true, null);
+ chooser.showDialog();
+ final PsiClass selectedClass = chooser.getSelected();
+ final String qName = selectedClass == null ? null : JVMNameUtil.getNonAnonymousClassName(selectedClass);
+
+ if (qName != null && qName.length() > 0) {
+ return ApplicationManager.getApplication().runWriteAction(new Computable<XBreakpoint<JavaExceptionBreakpointProperties>>() {
+ @Override
+ public XBreakpoint<JavaExceptionBreakpointProperties> compute() {
+ return XDebuggerManager.getInstance(project).getBreakpointManager().addBreakpoint(
+ JavaExceptionBreakpointType.this, new JavaExceptionBreakpointProperties(qName, ((PsiClassOwner)selectedClass.getContainingFile()).getPackageName()));
+ }
+ });
+ }
+ return null;
+ }
+
+ @Override
+ public Breakpoint createJavaBreakpoint(Project project, XBreakpoint<JavaExceptionBreakpointProperties> breakpoint) {
+ if (!XDebuggerManager.getInstance(project).getBreakpointManager().isDefaultBreakpoint(breakpoint)) {
+ return new ExceptionBreakpoint(project, breakpoint);
+ }
+ else {
+ return new AnyExceptionBreakpoint(project, breakpoint);
+ }
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java
new file mode 100644
index 000000000000..74a6f2df61cc
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java
@@ -0,0 +1,166 @@
+/*
+ * 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.ui.breakpoints;
+
+import com.intellij.CommonBundle;
+import com.intellij.debugger.DebuggerBundle;
+import com.intellij.debugger.HelpID;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+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.xdebugger.XDebuggerManager;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaFieldBreakpointProperties;
+
+import javax.swing.*;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Apr 26, 2005
+ */
+public class JavaFieldBreakpointType extends JavaLineBreakpointTypeBase<JavaFieldBreakpointProperties> implements JavaBreakpointType {
+ public JavaFieldBreakpointType() {
+ super("java-field", DebuggerBundle.message("field.watchpoints.tab.title"));
+ }
+
+ @NotNull
+ @Override
+ public Icon getEnabledIcon() {
+ return AllIcons.Debugger.Db_field_breakpoint;
+ }
+
+ @NotNull
+ @Override
+ public Icon getDisabledIcon() {
+ return AllIcons.Debugger.Db_disabled_field_breakpoint;
+ }
+
+ //@Override
+ protected String getHelpID() {
+ return HelpID.FIELD_WATCHPOINTS;
+ }
+
+ //@Override
+ public String getDisplayName() {
+ return DebuggerBundle.message("field.watchpoints.tab.title");
+ }
+
+ @Override
+ public String getShortText(XLineBreakpoint<JavaFieldBreakpointProperties> breakpoint) {
+ return getText(breakpoint);
+ }
+
+ public String getText(XLineBreakpoint<JavaFieldBreakpointProperties> breakpoint) {
+ //if(!isValid()) {
+ // return DebuggerBundle.message("status.breakpoint.invalid");
+ //}
+
+ JavaFieldBreakpointProperties properties = breakpoint.getProperties();
+ final String className = properties.myClassName;
+ return className != null && !className.isEmpty() ? className + "." + properties.myFieldName : properties.myFieldName;
+ }
+
+ @Nullable
+ @Override
+ public XBreakpointCustomPropertiesPanel<XLineBreakpoint<JavaFieldBreakpointProperties>> createCustomPropertiesPanel() {
+ return new FieldBreakpointPropertiesPanel();
+ }
+
+ @Nullable
+ @Override
+ public JavaFieldBreakpointProperties createProperties() {
+ return new JavaFieldBreakpointProperties();
+ }
+
+ @Nullable
+ @Override
+ public JavaFieldBreakpointProperties createBreakpointProperties(@NotNull VirtualFile file, int line) {
+ return new JavaFieldBreakpointProperties();
+ }
+
+ @Nullable
+ @Override
+ public XLineBreakpoint<JavaFieldBreakpointProperties> addBreakpoint(final Project project, JComponent parentComponent) {
+ final Ref<XLineBreakpoint> result = Ref.create(null);
+ AddFieldBreakpointDialog dialog = new AddFieldBreakpointDialog(project) {
+ protected boolean validateData() {
+ final String className = getClassName();
+ if (className.length() == 0) {
+ Messages.showMessageDialog(project, DebuggerBundle.message("error.field.breakpoint.class.name.not.specified"),
+ DebuggerBundle.message("add.field.breakpoint.dialog.title"), Messages.getErrorIcon());
+ return false;
+ }
+ final String fieldName = getFieldName();
+ if (fieldName.length() == 0) {
+ Messages.showMessageDialog(project, DebuggerBundle.message("error.field.breakpoint.field.name.not.specified"),
+ DebuggerBundle.message("add.field.breakpoint.dialog.title"), Messages.getErrorIcon());
+ return false;
+ }
+ PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project));
+ if (psiClass != null) {
+ final PsiFile psiFile = psiClass.getContainingFile();
+ Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
+ if(document != null) {
+ PsiField field = psiClass.findFieldByName(fieldName, true);
+ if(field != null) {
+ final int line = document.getLineNumber(field.getTextOffset());
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ XLineBreakpoint<JavaFieldBreakpointProperties> fieldBreakpoint = XDebuggerManager.getInstance(project).getBreakpointManager()
+ .addLineBreakpoint(JavaFieldBreakpointType.this, psiFile.getVirtualFile().getUrl(), line, new JavaFieldBreakpointProperties(fieldName, className));
+ result.set(fieldBreakpoint);
+ }
+ });
+ return true;
+ }
+ else {
+ Messages.showMessageDialog(project,
+ DebuggerBundle.message("error.field.breakpoint.field.not.found", className, fieldName, fieldName),
+ CommonBundle.getErrorTitle(),
+ Messages.getErrorIcon()
+ );
+ }
+ }
+ } else {
+ Messages.showMessageDialog(project,
+ DebuggerBundle.message("error.field.breakpoint.class.sources.not.found", className, fieldName, className),
+ CommonBundle.getErrorTitle(),
+ Messages.getErrorIcon()
+ );
+ }
+ return false;
+ }
+ };
+ dialog.show();
+ return result.get();
+ }
+
+ @Override
+ public Breakpoint createJavaBreakpoint(Project project, XBreakpoint breakpoint) {
+ return new FieldBreakpoint(project, breakpoint);
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.java
new file mode 100644
index 000000000000..99a37d4d3fbe
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.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.intellij.debugger.ui.breakpoints;
+
+import com.intellij.debugger.DebuggerBundle;
+import com.intellij.debugger.HelpID;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.xdebugger.XDebuggerUtil;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaLineBreakpointProperties;
+
+import javax.swing.*;
+import java.util.List;
+
+/**
+ * Base class for java line-connected exceptions (line, method, field)
+ * @author egor
+ */
+public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaBreakpointProperties> implements JavaBreakpointType {
+ public JavaLineBreakpointType() {
+ super("java-line", DebuggerBundle.message("line.breakpoints.tab.title"));
+ }
+
+ @NotNull
+ @Override
+ public Icon getEnabledIcon() {
+ return AllIcons.Debugger.Db_set_breakpoint;
+ }
+
+ @NotNull
+ @Override
+ public Icon getDisabledIcon() {
+ return AllIcons.Debugger.Db_disabled_breakpoint;
+ }
+
+ //@Override
+ protected String getHelpID() {
+ return HelpID.LINE_BREAKPOINTS;
+ }
+
+ //@Override
+ public String getDisplayName() {
+ return DebuggerBundle.message("line.breakpoints.tab.title");
+ }
+
+ @Override
+ public List<XBreakpointGroupingRule<XLineBreakpoint<JavaBreakpointProperties>, ?>> getGroupingRules() {
+ return XDebuggerUtil.getInstance().getGroupingByFileRuleAsList();
+ }
+
+ @Nullable
+ @Override
+ public JavaBreakpointProperties createProperties() {
+ return new JavaLineBreakpointProperties();
+ }
+
+ @Nullable
+ @Override
+ public JavaBreakpointProperties createBreakpointProperties(@NotNull VirtualFile file, int line) {
+ return new JavaLineBreakpointProperties();
+ }
+
+ @Override
+ public Breakpoint createJavaBreakpoint(Project project, XBreakpoint breakpoint) {
+ return new LineBreakpoint(project, breakpoint);
+ }
+
+ @Override
+ public int getPriority() {
+ return 100;
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java
new file mode 100644
index 000000000000..08b26bb7280e
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java
@@ -0,0 +1,157 @@
+/*
+ * 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.ui.breakpoints;
+
+import com.intellij.debugger.DebuggerManagerEx;
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.debugger.ui.JavaDebuggerSupport;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.Processor;
+import com.intellij.xdebugger.XDebuggerUtil;
+import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
+import com.intellij.xdebugger.breakpoints.XLineBreakpointType;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.JavaDebuggerEditorsProvider;
+import org.jetbrains.java.debugger.breakpoints.JavaBreakpointFiltersPanel;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties;
+
+/**
+ * Base class for java line-connected exceptions (line, method, field)
+ * @author egor
+ */
+public abstract class JavaLineBreakpointTypeBase<P extends JavaBreakpointProperties> extends XLineBreakpointType<P> {
+ public JavaLineBreakpointTypeBase(@NonNls @NotNull String id, @Nls @NotNull String title) {
+ super(id, title);
+ }
+
+ @Override
+ public boolean isAddBreakpointButtonVisible() {
+ return true;
+ }
+
+ @Override
+ public final boolean isSuspendThreadSupported() {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public final XBreakpointCustomPropertiesPanel<XLineBreakpoint<P>> createCustomRightPropertiesPanel(@NotNull Project project) {
+ return new JavaBreakpointFiltersPanel<P, XLineBreakpoint<P>>(project);
+ }
+
+ @Nullable
+ @Override
+ public final XDebuggerEditorsProvider getEditorsProvider(@NotNull XLineBreakpoint<P> breakpoint, @NotNull Project project) {
+ return new JavaDebuggerEditorsProvider();
+ }
+
+ @Override
+ public String getDisplayText(XLineBreakpoint<P> breakpoint) {
+ BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(JavaDebuggerSupport.getCurrentProject()).getBreakpointManager();
+ BreakpointWithHighlighter javaBreakpoint = (BreakpointWithHighlighter)breakpointManager.findBreakpoint(breakpoint);
+ if (javaBreakpoint != null) {
+ return javaBreakpoint.getDescription();
+ }
+ else {
+ return super.getDisplayText(breakpoint);
+ }
+ }
+
+ @Override
+ public final boolean canPutAt(@NotNull VirtualFile file, final int line, @NotNull Project project) {
+ PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
+ // JSPX supports jvm debugging, but not in XHTML files
+ // JS has it's own breakpoints
+ if (psiFile == null || psiFile.getVirtualFile().getFileType() == StdFileTypes.XHTML || psiFile.getVirtualFile().getFileType() == StdFileTypes.JS) {
+ return false;
+ }
+
+ FileType fileType = psiFile.getFileType();
+ if (!StdFileTypes.CLASS.equals(fileType) &&
+ !DebuggerUtils.supportsJVMDebugging(fileType) &&
+ !DebuggerUtils.supportsJVMDebugging(psiFile)) {
+ return false;
+ }
+
+ final Document document = FileDocumentManager.getInstance().getDocument(file);
+ final Ref<Class<? extends JavaLineBreakpointTypeBase>> result = Ref.create();
+ XDebuggerUtil.getInstance().iterateLine(project, document, line, new Processor<PsiElement>() {
+ @Override
+ public boolean process(PsiElement element) {
+ // avoid comments
+ if ((element instanceof PsiWhiteSpace) || (PsiTreeUtil.getParentOfType(element, PsiComment.class, false) != null)) {
+ return true;
+ }
+ PsiElement parent = element;
+ while(element != null) {
+ // skip modifiers
+ if (element instanceof PsiModifierList) {
+ element = element.getParent();
+ continue;
+ }
+
+ final int offset = element.getTextOffset();
+ if (offset >= 0) {
+ if (document.getLineNumber(offset) != line) {
+ break;
+ }
+ }
+ parent = element;
+ element = element.getParent();
+ }
+
+ if(parent instanceof PsiMethod) {
+ if (parent.getTextRange().getEndOffset() >= document.getLineEndOffset(line)) {
+ PsiCodeBlock body = ((PsiMethod)parent).getBody();
+ if (body != null) {
+ PsiStatement[] statements = body.getStatements();
+ if (statements.length > 0 && document.getLineNumber(statements[0].getTextOffset()) == line) {
+ result.set(JavaLineBreakpointType.class);
+ }
+ }
+ }
+ if (result.isNull()) {
+ result.set(JavaMethodBreakpointType.class);
+ }
+ }
+ else if (parent instanceof PsiField) {
+ if (result.isNull()) {
+ result.set(JavaFieldBreakpointType.class);
+ }
+ }
+ else {
+ result.set(JavaLineBreakpointType.class);
+ }
+ return true;
+ }
+ });
+ return result.get() == getClass();
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java
new file mode 100644
index 000000000000..94c3c77d80ce
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java
@@ -0,0 +1,122 @@
+/*
+ * 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.ui.breakpoints;
+
+import com.intellij.debugger.DebuggerBundle;
+import com.intellij.debugger.HelpID;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.StringBuilderSpinAllocator;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties;
+
+import javax.swing.*;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Apr 26, 2005
+ */
+public class JavaMethodBreakpointType extends JavaLineBreakpointTypeBase<JavaMethodBreakpointProperties> implements JavaBreakpointType {
+ public JavaMethodBreakpointType() {
+ super("java-method", DebuggerBundle.message("method.breakpoints.tab.title"));
+ }
+
+ @NotNull
+ @Override
+ public Icon getEnabledIcon() {
+ return AllIcons.Debugger.Db_method_breakpoint;
+ }
+
+ @NotNull
+ @Override
+ public Icon getDisabledIcon() {
+ return AllIcons.Debugger.Db_disabled_method_breakpoint;
+ }
+
+ //@Override
+ protected String getHelpID() {
+ return HelpID.METHOD_BREAKPOINTS;
+ }
+
+ @Override
+ public boolean isAddBreakpointButtonVisible() {
+ return false;
+ }
+
+ //@Override
+ public String getDisplayName() {
+ return DebuggerBundle.message("method.breakpoints.tab.title");
+ }
+
+ @Override
+ public String getShortText(XLineBreakpoint<JavaMethodBreakpointProperties> breakpoint) {
+ return getText(breakpoint);
+ }
+
+ static String getText(XBreakpoint<JavaMethodBreakpointProperties> breakpoint) {
+ final StringBuilder buffer = StringBuilderSpinAllocator.alloc();
+ try {
+ //if(isValid()) {
+ final String className = breakpoint.getProperties().myClassPattern;
+ final boolean classNameExists = className != null && className.length() > 0;
+ if (classNameExists) {
+ buffer.append(className);
+ }
+ if(breakpoint.getProperties().myMethodName != null) {
+ if (classNameExists) {
+ buffer.append(".");
+ }
+ buffer.append(breakpoint.getProperties().myMethodName);
+ }
+ //}
+ //else {
+ // buffer.append(DebuggerBundle.message("status.breakpoint.invalid"));
+ //}
+ return buffer.toString();
+ }
+ finally {
+ StringBuilderSpinAllocator.dispose(buffer);
+ }
+ }
+
+ @Nullable
+ @Override
+ public XBreakpointCustomPropertiesPanel createCustomPropertiesPanel() {
+ return new MethodBreakpointPropertiesPanel();
+ }
+
+ @Nullable
+ @Override
+ public JavaMethodBreakpointProperties createProperties() {
+ return new JavaMethodBreakpointProperties();
+ }
+
+ @Nullable
+ @Override
+ public JavaMethodBreakpointProperties createBreakpointProperties(@NotNull VirtualFile file, int line) {
+ return new JavaMethodBreakpointProperties();
+ }
+
+ @Override
+ public Breakpoint createJavaBreakpoint(Project project, XBreakpoint breakpoint) {
+ return new MethodBreakpoint(project, breakpoint);
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java
new file mode 100644
index 000000000000..dd28ee241f1a
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.ui.breakpoints;
+
+import com.intellij.debugger.DebuggerBundle;
+import com.intellij.debugger.HelpID;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.xdebugger.XDebuggerManager;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties;
+
+import javax.swing.*;
+
+/**
+ * @author Egor
+ */
+public class JavaWildcardMethodBreakpointType extends JavaBreakpointTypeBase<JavaMethodBreakpointProperties> implements JavaBreakpointType {
+ public JavaWildcardMethodBreakpointType() {
+ super("java-wildcard-method", DebuggerBundle.message("method.breakpoints.tab.title"));
+ }
+
+ @NotNull
+ @Override
+ public Icon getEnabledIcon() {
+ return AllIcons.Debugger.Db_method_breakpoint;
+ }
+
+ @NotNull
+ @Override
+ public Icon getDisabledIcon() {
+ return AllIcons.Debugger.Db_disabled_method_breakpoint;
+ }
+
+ //@Override
+ protected String getHelpID() {
+ return HelpID.METHOD_BREAKPOINTS;
+ }
+
+ //@Override
+ public String getDisplayName() {
+ return DebuggerBundle.message("method.breakpoints.tab.title");
+ }
+
+ @Override
+ public String getDisplayText(XBreakpoint<JavaMethodBreakpointProperties> breakpoint) {
+ return JavaMethodBreakpointType.getText(breakpoint);
+ }
+
+ @Nullable
+ @Override
+ public XBreakpointCustomPropertiesPanel<XBreakpoint<JavaMethodBreakpointProperties>> createCustomPropertiesPanel() {
+ return new MethodBreakpointPropertiesPanel();
+ }
+
+ //@Override
+ //public Key<MethodBreakpoint> getBreakpointCategory() {
+ // return MethodBreakpoint.CATEGORY;
+ //}
+
+ @Nullable
+ @Override
+ public JavaMethodBreakpointProperties createProperties() {
+ return new JavaMethodBreakpointProperties();
+ }
+
+ @Nullable
+ @Override
+ public XBreakpoint<JavaMethodBreakpointProperties> addBreakpoint(final Project project, JComponent parentComponent) {
+ final AddWildcardBreakpointDialog dialog = new AddWildcardBreakpointDialog(project);
+ dialog.show();
+ if (!dialog.isOK()) {
+ return null;
+ }
+ return ApplicationManager.getApplication().runWriteAction(new Computable<XBreakpoint<JavaMethodBreakpointProperties>>() {
+ @Override
+ public XBreakpoint<JavaMethodBreakpointProperties> compute() {
+ return XDebuggerManager.getInstance(project).getBreakpointManager().addBreakpoint(JavaWildcardMethodBreakpointType.this, new JavaMethodBreakpointProperties(
+ dialog.getClassPattern(),
+ dialog.getMethodName()));
+ }
+ });
+ }
+
+ @Override
+ public Breakpoint createJavaBreakpoint(Project project, XBreakpoint breakpoint) {
+ return new WildcardMethodBreakpoint(project, breakpoint);
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
index 307b9629b99f..2b3239122373 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
@@ -54,6 +54,7 @@ import com.intellij.util.Processor;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xdebugger.XDebuggerUtil;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.sun.jdi.*;
import com.sun.jdi.event.LocatableEvent;
import com.sun.jdi.request.BreakpointRequest;
@@ -74,12 +75,8 @@ public class LineBreakpoint extends BreakpointWithHighlighter {
private String myOwnerMethodName;
public static final @NonNls Key<LineBreakpoint> CATEGORY = BreakpointCategory.lookup("line_breakpoints");
- protected LineBreakpoint(Project project) {
- super(project);
- }
-
- public LineBreakpoint(Project project, RangeHighlighter highlighter) {
- super(project, highlighter);
+ protected LineBreakpoint(Project project, XBreakpoint xBreakpoint) {
+ super(project, xBreakpoint);
}
@Override
@@ -95,7 +92,7 @@ public class LineBreakpoint extends BreakpointWithHighlighter {
@Override
protected Icon getSetIcon(boolean isMuted) {
- if (REMOVE_AFTER_HIT) {
+ if (isRemoveAfterHit()) {
return isMuted ? AllIcons.Debugger.Db_muted_temporary_breakpoint : AllIcons.Debugger.Db_temporary_breakpoint;
}
return isMuted? AllIcons.Debugger.Db_muted_breakpoint : AllIcons.Debugger.Db_set_breakpoint;
@@ -108,7 +105,7 @@ public class LineBreakpoint extends BreakpointWithHighlighter {
@Override
protected Icon getVerifiedIcon(boolean isMuted) {
- if (REMOVE_AFTER_HIT) {
+ if (isRemoveAfterHit()) {
return isMuted ? AllIcons.Debugger.Db_muted_temporary_breakpoint : AllIcons.Debugger.Db_temporary_breakpoint;
}
return isMuted? AllIcons.Debugger.Db_muted_verified_breakpoint : AllIcons.Debugger.Db_verified_breakpoint;
@@ -349,9 +346,8 @@ public class LineBreakpoint extends BreakpointWithHighlighter {
}
private String getDisplayInfoInternal(boolean showPackageInfo, int totalTextLength) {
- final RangeHighlighter highlighter = getHighlighter();
- if(highlighter != null && highlighter.isValid() && isValid()) {
- final int lineNumber = (highlighter.getDocument().getLineNumber(highlighter.getStartOffset()) + 1);
+ if(isValid()) {
+ final int lineNumber = getSourcePosition().getLine() + 1;
String className = getClassName();
final boolean hasClassInfo = className != null && className.length() > 0;
final String methodName = getMethodName();
@@ -471,24 +467,19 @@ public class LineBreakpoint extends BreakpointWithHighlighter {
return ContextUtil.getContextElement(getSourcePosition());
}
- public static LineBreakpoint create(@NotNull Project project, @NotNull Document document, int lineIndex) {
- final RangeHighlighter highlighter = createHighlighter(project, document, lineIndex);
- if (highlighter == null) {
- return null;
- }
-
- LineBreakpoint breakpoint = new LineBreakpoint(project, highlighter);
+ public static LineBreakpoint create(@NotNull Project project, XBreakpoint xBreakpoint) {
+ LineBreakpoint breakpoint = new LineBreakpoint(project, xBreakpoint);
return (LineBreakpoint)breakpoint.init();
}
- @Override
- public boolean canMoveTo(SourcePosition position) {
- if (!super.canMoveTo(position)) {
- return false;
- }
- final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(position.getFile());
- return canAddLineBreakpoint(myProject, document, position.getLine());
- }
+ //@Override
+ //public boolean canMoveTo(SourcePosition position) {
+ // if (!super.canMoveTo(position)) {
+ // return false;
+ // }
+ // final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(position.getFile());
+ // return canAddLineBreakpoint(myProject, document, position.getLine());
+ //}
public static boolean canAddLineBreakpoint(Project project, final Document document, final int lineIndex) {
if (lineIndex < 0 || lineIndex >= document.getLineCount()) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java
deleted file mode 100644
index 0042074dc798..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpointFactory.java
+++ /dev/null
@@ -1,66 +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.ui.breakpoints;
-
-import com.intellij.debugger.DebuggerBundle;
-import com.intellij.debugger.HelpID;
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Key;
-import org.jdom.Element;
-
-import javax.swing.*;
-
-/**
- * @author Eugene Zhuravlev
- * Date: Apr 26, 2005
- */
-public class LineBreakpointFactory extends BreakpointFactory {
- @Override
- public Breakpoint createBreakpoint(Project project, final Element element) {
- return new LineBreakpoint(project);
- }
-
- @Override
- public Icon getIcon() {
- return AllIcons.Debugger.Db_set_breakpoint;
- }
-
- @Override
- public Icon getDisabledIcon() {
- return AllIcons.Debugger.Db_disabled_breakpoint;
- }
-
- @Override
- protected String getHelpID() {
- return HelpID.LINE_BREAKPOINTS;
- }
-
- @Override
- public String getDisplayName() {
- return DebuggerBundle.message("line.breakpoints.tab.title");
- }
-
- @Override
- public BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact) {
- return new LineBreakpointPropertiesPanel(project, compact);
- }
-
- @Override
- public Key<LineBreakpoint> getBreakpointCategory() {
- return LineBreakpoint.CATEGORY;
- }
-}
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 90a839d425d4..be10d56113f8 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
@@ -38,10 +38,13 @@ import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizerUtil;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.text.CharArrayUtil;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.Location;
import com.sun.jdi.Method;
@@ -52,31 +55,29 @@ import com.sun.jdi.event.MethodExitEvent;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.MethodEntryRequest;
import com.sun.jdi.request.MethodExitRequest;
+import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties;
import javax.swing.*;
import java.util.Iterator;
import java.util.Set;
-public class MethodBreakpoint extends BreakpointWithHighlighter {
+public class MethodBreakpoint extends BreakpointWithHighlighter<JavaMethodBreakpointProperties> {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.MethodBreakpoint");
- public boolean WATCH_ENTRY = true;
- public boolean WATCH_EXIT = true;
-
- @Nullable private String myMethodName;
@Nullable private JVMName mySignature;
private boolean myIsStatic;
public static final @NonNls Key<MethodBreakpoint> CATEGORY = BreakpointCategory.lookup("method_breakpoints");
- protected MethodBreakpoint(@NotNull Project project) {
- super(project);
+ protected MethodBreakpoint(@NotNull Project project, XBreakpoint breakpoint) {
+ super(project, breakpoint);
}
private MethodBreakpoint(@NotNull Project project, @NotNull RangeHighlighter highlighter) {
- super(project, highlighter);
+ super(project, highlighter, null);
}
public boolean isStatic() {
@@ -104,21 +105,25 @@ public class MethodBreakpoint extends BreakpointWithHighlighter {
}
public boolean isValid() {
- return super.isValid() && myMethodName != null;
+ return super.isValid() && getMethodName() != null;
}
protected void reload(@NotNull PsiFile psiFile) {
- myMethodName = null;
+ setMethodName(null);
mySignature = null;
MethodDescriptor descriptor = getMethodDescriptor(myProject, psiFile, getSourcePosition());
if (descriptor != null) {
- myMethodName = descriptor.methodName;
+ setMethodName(descriptor.methodName);
mySignature = descriptor.methodSignature;
myIsStatic = descriptor.isStatic;
}
+ PsiClass psiClass = getPsiClass();
+ if (psiClass != null) {
+ getProperties().myClassPattern = psiClass.getQualifiedName();
+ }
if (myIsStatic) {
- INSTANCE_FILTERS_ENABLED = false;
+ setInstanceFiltersEnabled(false);
}
}
@@ -130,7 +135,7 @@ public class MethodBreakpoint extends BreakpointWithHighlighter {
String signature = method.signature();
String name = method.name();
- if (myMethodName.equals(name) && mySignature.getName(debugProcess).equals(signature)) {
+ if (getMethodName().equals(name) && mySignature.getName(debugProcess).equals(signature)) {
hasMethod = true;
break;
}
@@ -144,7 +149,7 @@ public class MethodBreakpoint extends BreakpointWithHighlighter {
}
RequestManagerImpl requestManager = debugProcess.getRequestsManager();
- if (WATCH_ENTRY) {
+ if (isWatchEntry()) {
MethodEntryRequest entryRequest = (MethodEntryRequest)findRequest(debugProcess, MethodEntryRequest.class);
if (entryRequest == null) {
entryRequest = requestManager.createMethodEntryRequest(this);
@@ -157,7 +162,7 @@ public class MethodBreakpoint extends BreakpointWithHighlighter {
entryRequest.addClassFilter(classType);
debugProcess.getRequestsManager().enableRequest(entryRequest);
}
- if (WATCH_EXIT) {
+ if (isWatchExit()) {
MethodExitRequest exitRequest = (MethodExitRequest)findRequest(debugProcess, MethodExitRequest.class);
if (exitRequest == null) {
exitRequest = requestManager.createMethodExitRequest(this);
@@ -256,11 +261,11 @@ public class MethodBreakpoint extends BreakpointWithHighlighter {
if (classNameExists) {
buffer.append(className);
}
- if(myMethodName != null) {
+ if(getMethodName() != null) {
if (classNameExists) {
buffer.append(".");
}
- buffer.append(myMethodName);
+ buffer.append(getMethodName());
}
}
else {
@@ -281,16 +286,16 @@ public class MethodBreakpoint extends BreakpointWithHighlighter {
}
public boolean matchesEvent(@NotNull final LocatableEvent event, final DebugProcessImpl process) throws EvaluateException {
- if (myMethodName == null || mySignature == null) {
+ if (getMethodName() == null || mySignature == null) {
return false;
}
final Method method = event.location().method();
- return method != null && method.name().equals(myMethodName) && method.signature().equals(mySignature.getName(process));
+ return method != null && method.name().equals(getMethodName()) && method.signature().equals(mySignature.getName(process));
}
@Nullable
- public static MethodBreakpoint create(@NotNull Project project, @NotNull Document document, int lineIndex) {
- final MethodBreakpoint breakpoint = new MethodBreakpoint(project, createHighlighter(project, document, lineIndex));
+ public static MethodBreakpoint create(@NotNull Project project, XBreakpoint xBreakpoint) {
+ final MethodBreakpoint breakpoint = new MethodBreakpoint(project, xBreakpoint);
return (MethodBreakpoint)breakpoint.init();
}
@@ -362,6 +367,19 @@ public class MethodBreakpoint extends BreakpointWithHighlighter {
return null;
}
+ @Override
+ public void readExternal(@NotNull Element breakpointNode) throws InvalidDataException {
+ super.readExternal(breakpointNode);
+ try {
+ getProperties().WATCH_ENTRY = Boolean.valueOf(JDOMExternalizerUtil.readField(breakpointNode, "WATCH_ENTRY"));
+ } catch (Exception e) {
+ }
+ try {
+ getProperties().WATCH_EXIT = Boolean.valueOf(JDOMExternalizerUtil.readField(breakpointNode, "WATCH_EXIT"));
+ } catch (Exception e) {
+ }
+ }
+
public String toString() {
return getDescription();
}
@@ -376,6 +394,23 @@ public class MethodBreakpoint extends BreakpointWithHighlighter {
return false;
}
+ private boolean isWatchEntry() {
+ return getProperties().WATCH_ENTRY;
+ }
+
+ private boolean isWatchExit() {
+ return getProperties().WATCH_EXIT;
+ }
+
+ @Nullable
+ private String getMethodName() {
+ return getProperties().myMethodName;
+ }
+
+ private void setMethodName(@Nullable String methodName) {
+ getProperties().myMethodName = methodName;
+ }
+
private static final class MethodDescriptor {
String methodName;
JVMName methodSignature;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java
deleted file mode 100644
index a08e2a123ae6..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointFactory.java
+++ /dev/null
@@ -1,84 +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.ui.breakpoints;
-
-import com.intellij.debugger.DebuggerBundle;
-import com.intellij.debugger.DebuggerManagerEx;
-import com.intellij.debugger.HelpID;
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Key;
-import org.jdom.Element;
-
-import javax.swing.*;
-
-/**
- * @author Eugene Zhuravlev
- * Date: Apr 26, 2005
- */
-public class MethodBreakpointFactory extends BreakpointFactory{
- @Override
- public Breakpoint createBreakpoint(Project project, final Element element) {
- return element.getAttributeValue(WildcardMethodBreakpoint.JDOM_LABEL) != null? new WildcardMethodBreakpoint(project) : new MethodBreakpoint(project);
- }
-
- @Override
- public Icon getIcon() {
- return AllIcons.Debugger.Db_method_breakpoint;
- }
-
- @Override
- public Icon getDisabledIcon() {
- return AllIcons.Debugger.Db_disabled_method_breakpoint;
- }
-
- @Override
- protected String getHelpID() {
- return HelpID.METHOD_BREAKPOINTS;
- }
-
- @Override
- public String getDisplayName() {
- return DebuggerBundle.message("method.breakpoints.tab.title");
- }
-
- @Override
- public BreakpointPropertiesPanel createBreakpointPropertiesPanel(Project project, boolean compact) {
- return new MethodBreakpointPropertiesPanel(project, compact);
- }
-
- @Override
- public Key<MethodBreakpoint> getBreakpointCategory() {
- return MethodBreakpoint.CATEGORY;
- }
-
- @Override
- public boolean canAddBreakpoints() {
- return true;
- }
-
- @Override
- public WildcardMethodBreakpoint addBreakpoint(Project project) {
- AddWildcardBreakpointDialog dialog = new AddWildcardBreakpointDialog(project);
- dialog.show();
- WildcardMethodBreakpoint methodBreakpoint;
- methodBreakpoint = !dialog.isOK()
- ? null
- : DebuggerManagerEx.getInstanceEx(project).getBreakpointManager()
- .addMethodBreakpoint(dialog.getClassPattern(), dialog.getMethodName());
- return methodBreakpoint;
- }
-}
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 c50b6995d038..bf7419264105 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
@@ -21,24 +21,30 @@
package com.intellij.debugger.ui.breakpoints;
import com.intellij.debugger.DebuggerBundle;
-import com.intellij.openapi.project.Project;
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 org.jetbrains.annotations.NotNull;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-public class MethodBreakpointPropertiesPanel extends BreakpointPropertiesPanel {
+public class MethodBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPanel<XBreakpoint<JavaMethodBreakpointProperties>> {
private JCheckBox myWatchEntryCheckBox;
private JCheckBox myWatchExitCheckBox;
- public MethodBreakpointPropertiesPanel(final Project project, boolean compact) {
- super(project, MethodBreakpoint.CATEGORY, compact);
- }
+ //public MethodBreakpointPropertiesPanel(final Project project, boolean compact) {
+ // super(project, MethodBreakpoint.CATEGORY, compact);
+ //}
+
- protected JComponent createSpecialBox() {
+ @NotNull
+ @Override
+ public JComponent getComponent() {
JPanel _panel, _panel0;
myWatchEntryCheckBox = new JCheckBox(DebuggerBundle.message("label.method.breakpoint.properties.panel.method.entry"));
@@ -86,31 +92,15 @@ public class MethodBreakpointPropertiesPanel extends BreakpointPropertiesPanel {
return _panel;
}
- public void initFrom(Breakpoint breakpoint, boolean moreOptionsVisible) {
- super.initFrom(breakpoint, moreOptionsVisible);
- if (breakpoint instanceof MethodBreakpoint) {
- MethodBreakpoint methodBreakpoint = (MethodBreakpoint)breakpoint;
- myWatchEntryCheckBox.setSelected(methodBreakpoint.WATCH_ENTRY);
- myWatchExitCheckBox.setSelected(methodBreakpoint.WATCH_EXIT);
- }
- else if (breakpoint instanceof WildcardMethodBreakpoint){
- final WildcardMethodBreakpoint methodBreakpoint = ((WildcardMethodBreakpoint)breakpoint);
- myWatchEntryCheckBox.setSelected(methodBreakpoint.WATCH_ENTRY);
- myWatchExitCheckBox.setSelected(methodBreakpoint.WATCH_EXIT);
- }
+ @Override
+ public void loadFrom(@NotNull XBreakpoint<JavaMethodBreakpointProperties> breakpoint) {
+ myWatchEntryCheckBox.setSelected(breakpoint.getProperties().WATCH_ENTRY);
+ myWatchExitCheckBox.setSelected(breakpoint.getProperties().WATCH_EXIT);
}
- public void saveTo(Breakpoint breakpoint) {
- if (breakpoint instanceof MethodBreakpoint) {
- MethodBreakpoint methodBreakpoint = (MethodBreakpoint)breakpoint;
- methodBreakpoint.WATCH_ENTRY = myWatchEntryCheckBox.isSelected();
- methodBreakpoint.WATCH_EXIT = myWatchExitCheckBox.isSelected();
- }
- else if (breakpoint instanceof WildcardMethodBreakpoint){
- final WildcardMethodBreakpoint methodBreakpoint = ((WildcardMethodBreakpoint)breakpoint);
- methodBreakpoint.WATCH_ENTRY = myWatchEntryCheckBox.isSelected();
- methodBreakpoint.WATCH_EXIT = myWatchExitCheckBox.isSelected();
- }
- super.saveTo(breakpoint);
+ @Override
+ public void saveTo(@NotNull XBreakpoint<JavaMethodBreakpointProperties> breakpoint) {
+ breakpoint.getProperties().WATCH_ENTRY = myWatchEntryCheckBox.isSelected();
+ breakpoint.getProperties().WATCH_EXIT = myWatchExitCheckBox.isSelected();
}
} \ No newline at end of file
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java
index 82f617a14f6b..19a187da03c4 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java
@@ -18,10 +18,11 @@ package com.intellij.debugger.ui.breakpoints;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,18 +32,11 @@ import org.jetbrains.annotations.Nullable;
*/
public class RunToCursorBreakpoint extends LineBreakpoint {
private final boolean myRestoreBreakpoints;
- @Nullable
private final SourcePosition myCustomPosition;
-
- protected RunToCursorBreakpoint(@NotNull Project project, @NotNull RangeHighlighter highlighter, boolean restoreBreakpoints) {
- super(project, highlighter);
- setVisible(false);
- myRestoreBreakpoints = restoreBreakpoints;
- myCustomPosition = null;
- }
+ private String mySuspendPolicy;
protected RunToCursorBreakpoint(@NotNull Project project, @NotNull SourcePosition pos, boolean restoreBreakpoints) {
- super(project);
+ super(project, null);
myCustomPosition = pos;
setVisible(false);
myRestoreBreakpoints = restoreBreakpoints;
@@ -50,7 +44,51 @@ public class RunToCursorBreakpoint extends LineBreakpoint {
@Override
public SourcePosition getSourcePosition() {
- return myCustomPosition != null ? myCustomPosition : super.getSourcePosition();
+ return myCustomPosition;
+ }
+
+ @Override
+ public void reload() {
+ }
+
+ @Override
+ public String getSuspendPolicy() {
+ return mySuspendPolicy;
+ }
+
+ public void setSuspendPolicy(String policy) {
+ mySuspendPolicy = policy;
+ }
+
+ protected boolean isLogEnabled() {
+ return false;
+ }
+
+ @Override
+ protected boolean isLogExpressionEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ public boolean isCountFilterEnabled() {
+ return false;
+ }
+
+ public boolean isClassFiltersEnabled() {
+ return false;
+ }
+
+ public boolean isInstanceFiltersEnabled() {
+ return false;
+ }
+
+ @Override
+ protected boolean isConditionEnabled() {
+ return false;
}
public boolean isRestoreBreakpoints() {
@@ -63,6 +101,11 @@ public class RunToCursorBreakpoint extends LineBreakpoint {
}
@Override
+ public boolean isValid() {
+ return true;
+ }
+
+ @Override
protected boolean isMuted(@NotNull final DebugProcessImpl debugProcess) {
return false; // always enabled
}
@@ -74,17 +117,9 @@ public class RunToCursorBreakpoint extends LineBreakpoint {
return null;
}
- final RangeHighlighter highlighter = createHighlighter(project, document, lineIndex);
- if (highlighter == null) {
- return null;
- }
-
- final RunToCursorBreakpoint breakpoint = new RunToCursorBreakpoint(project, highlighter, restoreBreakpoints);
- final RangeHighlighter h = breakpoint.getHighlighter();
- if (h != null) {
- h.dispose();
- }
+ PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
+ SourcePosition pos = SourcePosition.createFromLine(psiFile, lineIndex);
- return (RunToCursorBreakpoint)breakpoint.init();
+ return new RunToCursorBreakpoint(project, pos, restoreBreakpoints);
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java
index 6e39e5ac1d29..af7d6755523a 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java
@@ -153,7 +153,7 @@ public class StepIntoBreakpoint extends RunToCursorBreakpoint {
if (pos != null) {
final StepIntoBreakpoint breakpoint = new StepIntoBreakpoint(project, pos, filter);
breakpoint.init();
- breakpoint.LOG_ENABLED = false;
+ breakpoint.setLogEnabled(false);
return breakpoint;
}
return null;
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 f6c0dc3c3ab2..295fddbaf187 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
@@ -23,15 +23,20 @@ import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.engine.requests.RequestManagerImpl;
+import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizerUtil;
import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.StringBuilderSpinAllocator;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.Location;
import com.sun.jdi.Method;
@@ -45,37 +50,33 @@ import com.sun.jdi.request.MethodExitRequest;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties;
import javax.swing.*;
import java.util.Iterator;
import java.util.Set;
-public class WildcardMethodBreakpoint extends Breakpoint {
+public class WildcardMethodBreakpoint extends Breakpoint<JavaMethodBreakpointProperties> {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.ExceptionBreakpoint");
- public boolean WATCH_ENTRY = true;
- public boolean WATCH_EXIT = true;
- private String myClassPattern;
- private String myMethodName;
-
public static final String JDOM_LABEL = "wildcard_breakpoint";
- public WildcardMethodBreakpoint(Project project) {
- super(project);
+ public WildcardMethodBreakpoint(Project project, XBreakpoint breakpoint) {
+ super(project, breakpoint);
}
public Key<MethodBreakpoint> getCategory() {
return MethodBreakpoint.CATEGORY;
}
- protected WildcardMethodBreakpoint(Project project, @NotNull String classPattern, @NotNull String methodName) {
- super(project);
- myClassPattern = classPattern;
- myMethodName = methodName;
+ protected WildcardMethodBreakpoint(Project project, @NotNull String classPattern, @NotNull String methodName, XBreakpoint breakpoint) {
+ super(project, breakpoint);
+ setClassPattern(classPattern);
+ setMethodName(methodName);
}
public String getClassName() {
- return myClassPattern;
+ return getClassPattern();
}
public @Nullable String getShortClassName() {
@@ -83,11 +84,15 @@ public class WildcardMethodBreakpoint extends Breakpoint {
}
public String getMethodName() {
- return myMethodName;
+ return getProperties().myMethodName;
}
public PsiClass getPsiClass() {
- return null;
+ return PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Computable<PsiClass>() {
+ public PsiClass compute() {
+ return getClassName() != null ? DebuggerUtilsEx.findClass(getClassName(), myProject, GlobalSearchScope.allScope(myProject)) : null;
+ }
+ });
}
public String getDisplayName() {
@@ -96,9 +101,9 @@ public class WildcardMethodBreakpoint extends Breakpoint {
}
final StringBuilder buffer = StringBuilderSpinAllocator.alloc();
try {
- buffer.append(myClassPattern);
+ buffer.append(getClassPattern());
buffer.append(".");
- buffer.append(myMethodName);
+ buffer.append(getMethodName());
buffer.append("()");
return buffer.toString();
}
@@ -108,7 +113,7 @@ public class WildcardMethodBreakpoint extends Breakpoint {
}
public Icon getIcon() {
- if (!ENABLED) {
+ if (!isEnabled()) {
final Breakpoint master = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().findMasterBreakpoint(this);
return master == null? AllIcons.Debugger.Db_disabled_method_breakpoint : AllIcons.Debugger.Db_dep_method_breakpoint;
}
@@ -124,12 +129,12 @@ public class WildcardMethodBreakpoint extends Breakpoint {
public void createRequest(DebugProcessImpl debugProcess) {
DebuggerManagerThreadImpl.assertIsManagerThread();
- if (!ENABLED || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) {
+ if (!isEnabled() || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) {
return;
}
try {
RequestManagerImpl requestManager = debugProcess.getRequestsManager();
- if (WATCH_ENTRY) {
+ if (isWatchEntry()) {
MethodEntryRequest entryRequest = (MethodEntryRequest)findRequest(debugProcess, MethodEntryRequest.class);
if (entryRequest == null) {
entryRequest = requestManager.createMethodEntryRequest(this);
@@ -137,10 +142,10 @@ public class WildcardMethodBreakpoint extends Breakpoint {
else {
entryRequest.disable();
}
- entryRequest.addClassFilter(myClassPattern);
+ entryRequest.addClassFilter(getClassPattern());
debugProcess.getRequestsManager().enableRequest(entryRequest);
}
- if (WATCH_EXIT) {
+ if (isWatchExit()) {
MethodExitRequest exitRequest = (MethodExitRequest)findRequest(debugProcess, MethodExitRequest.class);
if (exitRequest == null) {
exitRequest = requestManager.createMethodExitRequest(this);
@@ -148,7 +153,7 @@ public class WildcardMethodBreakpoint extends Breakpoint {
else {
exitRequest.disable();
}
- exitRequest.addClassFilter(myClassPattern);
+ exitRequest.addClassFilter(getClassPattern());
debugProcess.getRequestsManager().enableRequest(exitRequest);
}
}
@@ -212,19 +217,19 @@ public class WildcardMethodBreakpoint extends Breakpoint {
}
public boolean isValid() {
- return myClassPattern != null && myMethodName != null;
+ return getClassPattern() != null && getMethodName() != null;
}
- @SuppressWarnings({"HardCodedStringLiteral"}) public void writeExternal(Element parentNode) throws WriteExternalException {
- super.writeExternal(parentNode);
- parentNode.setAttribute(JDOM_LABEL, "true");
- if (myClassPattern != null) {
- parentNode.setAttribute("class_name", myClassPattern);
- }
- if (myMethodName != null) {
- parentNode.setAttribute("method_name", myMethodName);
- }
- }
+ //@SuppressWarnings({"HardCodedStringLiteral"}) public void writeExternal(Element parentNode) throws WriteExternalException {
+ // super.writeExternal(parentNode);
+ // parentNode.setAttribute(JDOM_LABEL, "true");
+ // if (getClassPattern() != null) {
+ // parentNode.setAttribute("class_name", getClassPattern());
+ // }
+ // if (getMethodName() != null) {
+ // parentNode.setAttribute("method_name", getMethodName());
+ // }
+ //}
public PsiElement getEvaluationElement() {
return null;
@@ -235,11 +240,20 @@ public class WildcardMethodBreakpoint extends Breakpoint {
//noinspection HardCodedStringLiteral
String className = parentNode.getAttributeValue("class_name");
- myClassPattern = className;
+ setClassPattern(className);
//noinspection HardCodedStringLiteral
String methodName = parentNode.getAttributeValue("method_name");
- myMethodName = methodName;
+ setMethodName(methodName);
+
+ try {
+ getProperties().WATCH_ENTRY = Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "WATCH_ENTRY"));
+ } catch (Exception e) {
+ }
+ try {
+ getProperties().WATCH_EXIT = Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "WATCH_EXIT"));
+ } catch (Exception e) {
+ }
if(className == null || methodName == null) {
throw new InvalidDataException();
@@ -248,10 +262,38 @@ public class WildcardMethodBreakpoint extends Breakpoint {
public boolean matchesEvent(final LocatableEvent event){
final Method method = event.location().method();
- return method != null && myMethodName.equals(method.name());
+ return method != null && getMethodName().equals(method.name());
+ }
+
+ public static WildcardMethodBreakpoint create(Project project, final String classPattern, final String methodName, XBreakpoint xBreakpoint) {
+ return new WildcardMethodBreakpoint(project, classPattern, methodName, xBreakpoint);
+ }
+
+ private boolean isWatchEntry() {
+ return getProperties().WATCH_ENTRY;
+ }
+
+ private void setWatchEntry(boolean WATCH_ENTRY) {
+ getProperties().WATCH_ENTRY = WATCH_ENTRY;
+ }
+
+ private boolean isWatchExit() {
+ return getProperties().WATCH_EXIT;
+ }
+
+ private void setWatchExit(boolean WATCH_EXIT) {
+ getProperties().WATCH_EXIT = WATCH_EXIT;
+ }
+
+ private String getClassPattern() {
+ return getProperties().myClassPattern;
+ }
+
+ private void setClassPattern(String classPattern) {
+ getProperties().myClassPattern = classPattern;
}
- public static WildcardMethodBreakpoint create(Project project, final String classPattern, final String methodName) {
- return new WildcardMethodBreakpoint(project, classPattern, methodName);
+ private void setMethodName(String methodName) {
+ getProperties().myMethodName = methodName;
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java
index 25cc97222726..c04f1bf63d67 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java
@@ -93,7 +93,7 @@ public abstract class DebuggerTreePanel extends UpdatableDebuggerView implements
getTree().rebuild(context);
}
}
- catch (VMDisconnectedException e) {
+ catch (VMDisconnectedException ignored) {
// ignored
}
}
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 30306a49ae84..788cb17b477e 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
@@ -83,11 +83,13 @@ public class FrameVariablesTree extends DebuggerTree {
}
}
+ @Override
protected void build(DebuggerContextImpl context) {
myAnyNewLocals = false;
buildWhenPaused(context, new RefreshFrameTreeCommand(context));
}
+ @Override
public void restoreNodeState(DebuggerTreeNodeImpl node) {
if (myAnyNewLocals) {
final NodeDescriptorImpl descriptor = node.getDescriptor();
@@ -107,6 +109,7 @@ public class FrameVariablesTree extends DebuggerTree {
}
+ @Override
protected DebuggerCommandImpl getBuildNodeCommand(final DebuggerTreeNodeImpl node) {
if (node.getDescriptor() instanceof StackFrameDescriptorImpl) {
return new BuildFrameTreeVariablesCommand(node);
@@ -119,6 +122,7 @@ public class FrameVariablesTree extends DebuggerTree {
super(stackNode);
}
+ @Override
protected void buildVariables(final StackFrameDescriptorImpl stackDescriptor, final EvaluationContextImpl evaluationContext) throws EvaluateException {
final DebuggerContextImpl debuggerContext = getDebuggerContext();
final SourcePosition sourcePosition = debuggerContext.getSourcePosition();
@@ -135,6 +139,7 @@ public class FrameVariablesTree extends DebuggerTree {
final EvaluationContextImpl evalContext = debuggerContext.createEvaluationContext();
final Pair<Set<String>, Set<TextWithImports>> usedVars =
ApplicationManager.getApplication().runReadAction(new Computable<Pair<Set<String>, Set<TextWithImports>>>() {
+ @Override
public Pair<Set<String>, Set<TextWithImports>> compute() {
return findReferencedVars(visibleVariables.keySet(), sourcePosition, evalContext);
}
@@ -396,6 +401,7 @@ public class FrameVariablesTree extends DebuggerTree {
super(context);
}
+ @Override
public void contextAction() throws Exception {
DebuggerTreeNodeImpl rootNode;
@@ -433,7 +439,7 @@ public class FrameVariablesTree extends DebuggerTree {
rootNode.add(MessageDescriptor.THREAD_IS_RUNNING);
}
}
- catch (ObjectCollectedException e) {
+ catch (ObjectCollectedException ignored) {
rootNode.add(new MessageDescriptor(DebuggerBundle.message("label.thread.node.thread.collected", currentThread.name())));
}
}
@@ -448,12 +454,14 @@ public class FrameVariablesTree extends DebuggerTree {
final DebuggerTreeNodeImpl rootNode1 = rootNode;
DebuggerInvocationUtil.swingInvokeLater(getProject(), new Runnable() {
+ @Override
public void run() {
getMutableModel().setRoot(rootNode1);
treeChanged();
final TreeModel model = getModel();
model.addTreeModelListener(new TreeModelAdapter() {
+ @Override
public void treeStructureChanged(TreeModelEvent e) {
final Object[] path = e.getPath();
if (path.length > 0 && path[path.length - 1] == rootNode1) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java
index 9967b70eb485..d0d25f1808b5 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesList.java
@@ -35,15 +35,18 @@ public class FramesList extends DebuggerFramesList {
doInit();
}
+ @Override
protected FramesListRenderer createListRenderer() {
return new FramesListRenderer();
}
+ @Override
protected void onFrameChanged(final Object selectedValue) {
final StackFrameDescriptorImpl descriptor = selectedValue instanceof StackFrameDescriptorImpl? (StackFrameDescriptorImpl)selectedValue : null;
final Method newMethod = descriptor != null? descriptor.getMethod() : null;
if (!Comparing.equal(mySelectedMethod, newMethod)) {
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
repaint();
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java
index c6e62281b143..c3368cd5c4f9 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java
@@ -16,14 +16,14 @@
package com.intellij.debugger.ui.impl;
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl;
-import com.intellij.ui.JBColor;
-import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.util.Comparing;
import com.intellij.ui.ColoredListCellRenderer;
+import com.intellij.ui.JBColor;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ui.UIUtil;
+import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.intellij.xdebugger.ui.DebuggerColors;
import com.sun.jdi.Method;
@@ -38,6 +38,7 @@ class FramesListRenderer extends ColoredListCellRenderer {
myColorScheme = EditorColorsManager.getInstance().getGlobalScheme();
}
+ @Override
protected void customizeCellRenderer(final JList list, final Object item, final int index, final boolean selected, final boolean hasFocus) {
if (!(item instanceof StackFrameDescriptorImpl)) {
append(item.toString(), SimpleTextAttributes.GRAYED_ATTRIBUTES);
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java
index 4b3f145995b2..e059e789254b 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java
@@ -59,10 +59,12 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
setLvalue(!field.isFinal());
}
+ @Override
public Field getField() {
return myField;
}
+ @Override
public ObjectReference getObject() {
return myObject;
}
@@ -131,6 +133,7 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
}
}
+ @Override
public void setAncestor(NodeDescriptor oldDescriptor) {
super.setAncestor(oldDescriptor);
final Boolean isPrimitive = ((FieldDescriptorImpl)oldDescriptor).myIsPrimitive;
@@ -141,6 +144,7 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
}
+ @Override
public boolean isPrimitive() {
if (myIsPrimitive == null) {
final Value value = getValue();
@@ -154,12 +158,13 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
return myIsPrimitive.booleanValue();
}
+ @Override
public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
DebuggerManagerThreadImpl.assertIsManagerThread();
try {
return (myObject != null) ? myObject.getValue(myField) : myField.declaringType().getValue(myField);
}
- catch (ObjectCollectedException e) {
+ catch (ObjectCollectedException ignored) {
throw EvaluateExceptionUtil.OBJECT_WAS_COLLECTED;
}
}
@@ -168,6 +173,7 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
return myIsStatic;
}
+ @Override
public String getName() {
final String fieldName = myField.name();
if (isOuterLocalVariableValue() && NodeRendererSettings.getInstance().getClassRenderer().SHOW_VAL_FIELDS_AS_LOCAL_VARIABLES) {
@@ -180,11 +186,12 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
try {
return DebuggerUtils.isSynthetic(myField) && myField.name().startsWith(OUTER_LOCAL_VAR_FIELD_PREFIX);
}
- catch (UnsupportedOperationException e) {
+ catch (UnsupportedOperationException ignored) {
return false;
}
}
+ @Override
public String calcValueName() {
final ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer();
StringBuilder buf = StringBuilderSpinAllocator.alloc();
@@ -201,6 +208,7 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
}
}
+ @Override
public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException {
PsiElementFactory elementFactory = JavaPsiFacade.getInstance(context.getProject()).getElementFactory();
String fieldName;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java
index 026f2ad6b4b9..6f2aa4e09f0d 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MessageDescriptor.java
@@ -59,17 +59,21 @@ public class MessageDescriptor extends NodeDescriptorImpl {
return myKind;
}
+ @Override
public String getLabel() {
return myMessage;
}
+ @Override
public boolean isExpandable() {
return false;
}
+ @Override
public void setContext(EvaluationContextImpl context) {
}
+ @Override
protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener) throws EvaluateException {
DebuggerManagerThreadImpl.assertIsManagerThread();
return myMessage;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java
index a009733a39a9..f2f5b1c23283 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorImpl.java
@@ -52,15 +52,21 @@ public abstract class NodeDescriptorImpl implements NodeDescriptor {
private final List<NodeDescriptorImpl> myChildren = new ArrayList<NodeDescriptorImpl>();
private static final Key<Map<ObjectReference, ValueMarkup>> MARKUP_MAP_KEY = new Key<Map<ObjectReference, ValueMarkup>>("ValueMarkupMap");
+ @Override
public String getName() {
return null;
}
+ @Override
public <T> T getUserData(Key<T> key) {
- if(myUserData == null) return null;
- return (T) myUserData.get(key);
+ if (myUserData == null) {
+ return null;
+ }
+ //noinspection unchecked
+ return (T)myUserData.get(key);
}
+ @Override
public <T> void putUserData(Key<T> key, T value) {
if(myUserData == null) {
myUserData = new HashMap<Key, Object>();
@@ -91,12 +97,12 @@ public abstract class NodeDescriptorImpl implements NodeDescriptor {
protected abstract String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener labelListener) throws EvaluateException;
- private EvaluateException processException(Exception e) {
- if(e instanceof InconsistentDebugInfoException) {
+ private static EvaluateException processException(Exception e) {
+ if (e instanceof InconsistentDebugInfoException) {
return new EvaluateException(DebuggerBundle.message("error.inconsistent.debug.info"), null);
}
- else if(e instanceof InvalidStackFrameException) {
+ else if (e instanceof InvalidStackFrameException) {
return new EvaluateException(DebuggerBundle.message("error.invalid.stackframe"), null);
}
else {
@@ -104,6 +110,7 @@ public abstract class NodeDescriptorImpl implements NodeDescriptor {
}
}
+ @Override
public void displayAs(NodeDescriptor descriptor) {
if (descriptor instanceof NodeDescriptorImpl) {
final NodeDescriptorImpl that = (NodeDescriptorImpl)descriptor;
@@ -122,6 +129,7 @@ public abstract class NodeDescriptorImpl implements NodeDescriptor {
return myEvaluateException;
}
+ @Override
public String getLabel() {
return myLabel;
}
@@ -149,6 +157,7 @@ public abstract class NodeDescriptorImpl implements NodeDescriptor {
return myChildren;
}
+ @Override
public void setAncestor(NodeDescriptor oldDescriptor) {
displayAs(oldDescriptor);
}
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 41a5384ae19b..8e11e545dcd0 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
@@ -34,6 +34,8 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.ui.FileColorManager;
import com.intellij.util.StringBuilderSpinAllocator;
+import com.intellij.util.ui.TextTransferable;
+import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.sun.jdi.*;
import org.jetbrains.annotations.Nullable;
@@ -50,6 +52,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
private int myUiIndex;
private String myName = null;
private Location myLocation;
+ private final XStackFrame myXStackFrame;
private MethodsTracker.MethodOccurrence myMethodOccurrence;
private boolean myIsSynthetic;
private boolean myIsInLibraryContent;
@@ -67,6 +70,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
myMethodOccurrence = tracker.getMethodOccurrence(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;
@@ -83,7 +87,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
}
});
}
- catch(InternalException e) {
+ catch (InternalException e) {
LOG.info(e);
myLocation = null;
myMethodOccurrence = tracker.getMethodOccurrence(null);
@@ -97,16 +101,20 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
myIsSynthetic = false;
myIsInLibraryContent = false;
}
+
+ myXStackFrame = myLocation == null ? null : getDebugProcess().getPositionManager().createStackFrame(myLocation);
}
public int getUiIndex() {
return myUiIndex;
}
+ @Override
public StackFrameProxyImpl getFrameProxy() {
return myFrame;
}
+ @Override
public DebugProcess getDebugProcess() {
return myFrame.getVirtualMachine().getDebugProcess();
}
@@ -140,12 +148,21 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
return null;
}
+ @Override
public String getName() {
return myName;
}
+ @Override
protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener descriptorLabelListener) throws EvaluateException {
DebuggerManagerThreadImpl.assertIsManagerThread();
+
+ if (myXStackFrame != null) {
+ TextTransferable.ColoredStringBuilder builder = new TextTransferable.ColoredStringBuilder();
+ myXStackFrame.customizePresentation(builder);
+ return builder.getBuilder().toString();
+ }
+
if (myLocation == null) {
return "";
}
@@ -159,7 +176,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
label.append("()");
}
if (settings.SHOW_LINE_NUMBER) {
- String lineNumber = null;
+ String lineNumber;
try {
lineNumber = Integer.toString(myLocation.lineNumber());
}
@@ -172,7 +189,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
}
}
if (settings.SHOW_CLASS_NAME) {
- String name = null;
+ String name;
try {
ReferenceType refType = myLocation.declaringType();
name = refType != null ? refType.name() : null;
@@ -206,7 +223,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
label.append(", ");
label.append(sourceName);
}
- catch (AbsentInformationException exception) {
+ catch (AbsentInformationException ignored) {
}
}
return label.toString();
@@ -220,10 +237,12 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
return getFrameProxy().equals(d.getFrameProxy());
}
+ @Override
public boolean isExpandable() {
return true;
}
+ @Override
public final void setContext(EvaluationContextImpl context) {
myIcon = calcIcon();
}
@@ -246,7 +265,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
return AllIcons.Debugger.Db_obsolete;
}
}
- catch (EvaluateException e) {
+ catch (EvaluateException ignored) {
}
return AllIcons.Debugger.StackFrame;
}
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java b/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java
index 21cdb36a3a4e..5df69039a726 100644
--- a/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java
@@ -1,16 +1,28 @@
package org.jetbrains.java.debugger;
+import com.intellij.debugger.engine.evaluation.CodeFragmentKind;
+import com.intellij.debugger.engine.evaluation.TextWithImports;
+import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
+import com.intellij.debugger.ui.DebuggerExpressionComboBox;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaCodeFragmentFactory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.intellij.xdebugger.XSourcePosition;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProviderBase;
+import com.intellij.xdebugger.impl.breakpoints.ui.XDebuggerComboBoxProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase {
+import javax.swing.*;
+
+public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase implements XDebuggerComboBoxProvider {
@NotNull
@Override
public FileType getFileType() {
@@ -21,4 +33,77 @@ public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase {
protected PsiFile createExpressionCodeFragment(@NotNull Project project, @NotNull String text, @Nullable PsiElement context, boolean isPhysical) {
return JavaCodeFragmentFactory.getInstance(project).createExpressionCodeFragment(text, context, null, isPhysical);
}
+
+ @Override
+ public XBreakpointCustomPropertiesPanel<XBreakpoint<?>> createConditionComboBoxPanel(Project project,
+ XDebuggerEditorsProvider debuggerEditorsProvider,
+ String historyId,
+ XSourcePosition sourcePosition) {
+ return new ExpressionComboBoxPanel(project, historyId, sourcePosition) {
+ @Override
+ public void saveTo(@NotNull XBreakpoint<?> breakpoint) {
+ TextWithImports text = myComboBox.getText();
+ final String condition = !text.getText().isEmpty() ? text.toExternalForm() : null;
+ breakpoint.setCondition(condition);
+ if (condition != null) {
+ myComboBox.addRecent(text);
+ }
+ }
+
+ @Override
+ public void loadFrom(@NotNull XBreakpoint<?> breakpoint) {
+ myComboBox.setText(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, StringUtil.notNullize(breakpoint.getCondition())));
+ }
+ };
+ }
+
+ @Override
+ public XBreakpointCustomPropertiesPanel<XBreakpoint<?>> createLogExpressionComboBoxPanel(Project project,
+ XDebuggerEditorsProvider debuggerEditorsProvider,
+ String historyId,
+ XSourcePosition sourcePosition) {
+ return new ExpressionComboBoxPanel(project, historyId, sourcePosition) {
+ @Override
+ public void saveTo(@NotNull XBreakpoint<?> breakpoint) {
+ TextWithImports text = myComboBox.getText();
+ breakpoint.setLogExpression(myComboBox.isEnabled() && !text.getText().isEmpty() ? text.toExternalForm() : null);
+ if (text != null) {
+ myComboBox.addRecent(text);
+ }
+ }
+
+ @Override
+ public void loadFrom(@NotNull XBreakpoint<?> breakpoint) {
+ myComboBox.setText(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, StringUtil.notNullize(breakpoint.getLogExpression())));
+ }
+ };
+ }
+
+ private abstract class ExpressionComboBoxPanel extends XBreakpointCustomPropertiesPanel<XBreakpoint<?>> {
+ protected final DebuggerExpressionComboBox myComboBox;
+
+ private ExpressionComboBoxPanel(Project project,
+ String historyId,
+ XSourcePosition sourcePosition) {
+ myComboBox = new DebuggerExpressionComboBox(project, historyId);
+ if (sourcePosition != null) {
+ PsiElement element = getContextElement(sourcePosition.getFile(), sourcePosition.getOffset(), project);
+ myComboBox.setContext(element);
+ }
+ else {
+ myComboBox.setContext(null);
+ }
+ }
+
+ @NotNull
+ @Override
+ public JComponent getComponent() {
+ return myComboBox;
+ }
+
+ @Override
+ public void dispose() {
+ myComboBox.dispose();
+ }
+ }
} \ No newline at end of file
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapter.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapter.java
deleted file mode 100644
index a6705848a44d..000000000000
--- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapter.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package org.jetbrains.java.debugger.breakpoints;
-
-import com.intellij.debugger.engine.evaluation.CodeFragmentKind;
-import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
-import com.intellij.debugger.engine.requests.RequestManagerImpl;
-import com.intellij.debugger.settings.DebuggerSettings;
-import com.intellij.debugger.ui.breakpoints.LineBreakpoint;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.markup.RangeHighlighter;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
-import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
-import com.intellij.xdebugger.impl.breakpoints.XLineBreakpointImpl;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Arrays;
-
-public class JavaBreakpointAdapter extends JavaBreakpointAdapterBase {
- private static final Key<LineBreakpoint> OLD_JAVA_BREAKPOINT_KEY = Key.create("oldJavaBreakpoint");
-
- public JavaBreakpointAdapter(Project project) {
- super(project);
- }
-
- @Override
- protected void configureCreatedBreakpoint(LineBreakpoint oldBreakpoint, XLineBreakpoint<XBreakpointProperties> breakpoint) {
- oldBreakpoint.SUSPEND_POLICY = transformSuspendPolicy(breakpoint);
- applyCondition(oldBreakpoint, breakpoint);
- applyFilters(oldBreakpoint, breakpoint);
- }
-
- private boolean applyFilters(LineBreakpoint oldBreakpoint, XLineBreakpoint<XBreakpointProperties> breakpoint) {
- boolean changed = false;
- JavaBreakpointProperties properties = (JavaBreakpointProperties)breakpoint.getProperties();
-
- changed |= oldBreakpoint.COUNT_FILTER_ENABLED != properties.COUNT_FILTER_ENABLED;
- oldBreakpoint.COUNT_FILTER_ENABLED = properties.COUNT_FILTER_ENABLED;
-
- changed |= oldBreakpoint.COUNT_FILTER != properties.COUNT_FILTER;
- oldBreakpoint.COUNT_FILTER = properties.COUNT_FILTER;
-
- changed |= oldBreakpoint.CLASS_FILTERS_ENABLED != properties.CLASS_FILTERS_ENABLED;
- oldBreakpoint.CLASS_FILTERS_ENABLED = properties.CLASS_FILTERS_ENABLED;
-
- changed |= !Arrays.equals(oldBreakpoint.getClassFilters(), properties.getClassFilters());
- oldBreakpoint.setClassFilters(properties.getClassFilters());
-
- changed |= !Arrays.equals(oldBreakpoint.getClassExclusionFilters(), properties.getClassExclusionFilters());
- oldBreakpoint.setClassExclusionFilters(properties.getClassExclusionFilters());
-
- changed |= oldBreakpoint.INSTANCE_FILTERS_ENABLED != properties.INSTANCE_FILTERS_ENABLED;
- oldBreakpoint.INSTANCE_FILTERS_ENABLED = properties.INSTANCE_FILTERS_ENABLED;
-
- changed |= !Arrays.equals(oldBreakpoint.getInstanceFilters(), properties.getInstanceFilters());
- oldBreakpoint.setInstanceFilters(properties.getInstanceFilters());
-
- return changed;
- }
-
- private static void applyCondition(LineBreakpoint oldBreakpoint, XLineBreakpoint<XBreakpointProperties> breakpoint) {
- if (breakpoint.getCondition() != null) {
- oldBreakpoint.CONDITION_ENABLED = true;
- oldBreakpoint.setCondition(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, breakpoint.getCondition()));
- }
- else {
- oldBreakpoint.CONDITION_ENABLED = false;
- if (!StringUtil.isEmptyOrSpaces(oldBreakpoint.getCondition().getText())) {
- oldBreakpoint.setCondition(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, ""));
- }
- }
- }
-
- @Override
- protected void updateBreakpoint(LineBreakpoint jBreakpoint, XLineBreakpoint<XBreakpointProperties> breakpoint) {
- boolean changed = false;
- if (jBreakpoint.ENABLED != breakpoint.isEnabled()) {
- jBreakpoint.ENABLED = breakpoint.isEnabled();
- changed = true;
- }
-
- String suspendPolicy = transformSuspendPolicy(breakpoint);
- if (jBreakpoint.SUSPEND_POLICY != suspendPolicy) {
- jBreakpoint.SUSPEND_POLICY = suspendPolicy;
- changed = true;
- }
-
- if (StringUtil.compare(breakpoint.getCondition(), jBreakpoint.getCondition().getText(), false) != 0) {
- applyCondition(jBreakpoint, breakpoint);
- changed = true;
- }
-
- if (applyFilters(jBreakpoint, breakpoint)) {
- changed = true;
- }
-
- if (jBreakpoint.getSourcePosition().getLine() != breakpoint.getLine()) {
- jBreakpoint.reload();
- changed = true;
- }
-
- if (changed) {
- RequestManagerImpl.updateRequests(jBreakpoint);
- jBreakpoint.updateUI();
- }
- }
-
- @Override
- protected LineBreakpoint findBreakpoint(XLineBreakpoint<XBreakpointProperties> breakpoint) {
- return OLD_JAVA_BREAKPOINT_KEY.get(breakpoint);
- }
-
- public LineBreakpoint getOrCreate(XLineBreakpoint<XBreakpointProperties> breakpoint) {
- LineBreakpoint oldBreakpoint = findBreakpoint(breakpoint);
- if (oldBreakpoint == null) {
- oldBreakpoint = createBreakpoint(breakpoint);
- OLD_JAVA_BREAKPOINT_KEY.set(breakpoint, oldBreakpoint);
- }
- return oldBreakpoint;
- }
-
- @Override
- public void breakpointRemoved(@NotNull XLineBreakpoint<XBreakpointProperties> breakpoint) {
- LineBreakpoint jBreakpoint = findBreakpoint(breakpoint);
- if (jBreakpoint != null) {
- jBreakpoint.delete();
- }
- }
-
- @Override
- protected LineBreakpoint doCreateInstance(Project project, Document document, XLineBreakpoint<XBreakpointProperties> breakpoint) {
- LineBreakpoint lineBreakpoint = new LineBreakpoint(project, ((XLineBreakpointImpl)breakpoint).getHighlighter()) {
- @Override
- protected void setEditorFilter(RangeHighlighter highlighter) {
- }
- };
-
- lineBreakpoint.setVisible(false);
- lineBreakpoint.init();
- return lineBreakpoint;
- }
-
- private static String transformSuspendPolicy(XLineBreakpoint<XBreakpointProperties> breakpoint) {
- switch (breakpoint.getSuspendPolicy()) {
- case ALL:
- return DebuggerSettings.SUSPEND_ALL;
- case THREAD:
- return DebuggerSettings.SUSPEND_THREAD;
- case NONE:
- return DebuggerSettings.SUSPEND_NONE;
-
- default:
- throw new IllegalArgumentException("unknown suspend policy");
- }
- }
-}
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapterBase.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapterBase.java
index 6b249356d340..686de9aad6eb 100644
--- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapterBase.java
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapterBase.java
@@ -56,11 +56,11 @@ public abstract class JavaBreakpointAdapterBase extends XBreakpointAdapter<XLine
LineBreakpoint oldBreakpoint = doCreateInstance(project, document, breakpoint);
oldBreakpoint.setVisible(false);
oldBreakpoint.updateUI();
- oldBreakpoint.ENABLED = breakpoint.isEnabled();
+ oldBreakpoint.setEnabled(breakpoint.isEnabled());
return oldBreakpoint;
}
- protected LineBreakpoint doCreateInstance(Project project, Document document, XLineBreakpoint<XBreakpointProperties> breakpoint) {
- return LineBreakpoint.create(project, document, breakpoint.getLine());
+ protected LineBreakpoint doCreateInstance(Project project, Document document, XLineBreakpoint<XBreakpointProperties> xBreakpoint) {
+ return LineBreakpoint.create(project, xBreakpoint);
}
}
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointPropertiesPanel.form b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.form
index db560b3feaeb..39507678f8ff 100644
--- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointPropertiesPanel.form
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.form
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.java.debugger.breakpoints.JavaBreakpointPropertiesPanel">
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.java.debugger.breakpoints.JavaBreakpointFiltersPanel">
<grid id="27dc6" 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>
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointPropertiesPanel.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java
index e575973ea0ba..2afcf0fd339f 100644
--- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointPropertiesPanel.java
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java
@@ -26,11 +26,11 @@ import com.intellij.ui.FieldPanel;
import com.intellij.ui.MultiLineTooltipUI;
import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.xdebugger.XSourcePosition;
-import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
-import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties;
import javax.swing.*;
import java.awt.*;
@@ -44,7 +44,7 @@ import java.util.List;
/**
* @author egor
*/
-public class JavaBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPanel<XLineBreakpoint<XBreakpointProperties>> {
+public class JavaBreakpointFiltersPanel<T extends JavaBreakpointProperties, B extends XBreakpoint<T>> extends XBreakpointCustomPropertiesPanel<B> {
private JPanel myConditionsPanel;
private JPanel myInstanceFiltersPanel;
private JCheckBox myInstanceFiltersCheckBox;
@@ -66,7 +66,7 @@ public class JavaBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPa
private PsiClass myBreakpointPsiClass;
- public JavaBreakpointPropertiesPanel(Project project) {
+ public JavaBreakpointFiltersPanel(Project project) {
myProject = project;
myInstanceFiltersField = new FieldPanel(new MyTextField(), "", null,
new ActionListener() {
@@ -135,8 +135,8 @@ public class JavaBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPa
}
@Override
- public boolean isVisibleOnPopup(@NotNull XLineBreakpoint<XBreakpointProperties> breakpoint) {
- JavaBreakpointProperties properties = (JavaBreakpointProperties)breakpoint.getProperties();
+ 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;
}
@@ -144,8 +144,8 @@ public class JavaBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPa
}
@Override
- public void saveTo(@NotNull XLineBreakpoint<XBreakpointProperties> breakpoint) {
- JavaBreakpointProperties properties = (JavaBreakpointProperties)breakpoint.getProperties();
+ public void saveTo(@NotNull B breakpoint) {
+ JavaBreakpointProperties properties = breakpoint.getProperties();
if (properties == null) {
return;
}
@@ -179,8 +179,8 @@ public class JavaBreakpointPropertiesPanel extends XBreakpointCustomPropertiesPa
}
@Override
- public void loadFrom(@NotNull XLineBreakpoint<XBreakpointProperties> breakpoint) {
- JavaBreakpointProperties properties = (JavaBreakpointProperties)breakpoint.getProperties();
+ 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));
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java
deleted file mode 100644
index 5e55a49658f8..000000000000
--- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointType.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.jetbrains.java.debugger.breakpoints;
-
-import com.intellij.debugger.DebuggerBundle;
-import com.intellij.debugger.engine.DebuggerUtils;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.StdFileTypes;
-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.util.SystemProperties;
-import com.intellij.xdebugger.XDebuggerUtil;
-import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
-import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
-import com.intellij.xdebugger.breakpoints.XLineBreakpointTypeBase;
-import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
-import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
-import org.jetbrains.annotations.Contract;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.java.debugger.JavaDebuggerEditorsProvider;
-
-import java.util.List;
-
-public class JavaBreakpointType extends XLineBreakpointTypeBase {
- public JavaBreakpointType() {
- super("java", DebuggerBundle.message("java.breakpoint.title"), new JavaDebuggerEditorsProvider());
- }
-
- @Override
- public boolean canPutAt(@NotNull final VirtualFile file, final int line, @NotNull Project project) {
- return SystemProperties.getBooleanProperty("java.debugger.xBreakpoint", false) &&
- doCanPutAt(PsiManager.getInstance(project).findFile(file));
- }
-
- @Override
- public boolean isSuspendThreadSupported() {
- return true;
- }
-
- @Override
- public List<XBreakpointGroupingRule<XLineBreakpoint<XBreakpointProperties>, ?>> getGroupingRules() {
- return XDebuggerUtil.getInstance().getGroupingByFileRuleAsList();
- }
-
- @Contract("null -> false")
- public static boolean doCanPutAt(@Nullable PsiFile psiFile) {
- // JSPX supports jvm debugging, but not in XHTML files
- if (psiFile == null || psiFile.getVirtualFile().getFileType() == StdFileTypes.XHTML) {
- return false;
- }
-
- FileType fileType = psiFile.getFileType();
- return StdFileTypes.CLASS.equals(fileType) || DebuggerUtils.supportsJVMDebugging(fileType) || DebuggerUtils.supportsJVMDebugging(psiFile);
- }
-
- @Nullable
- @Override
- public XBreakpointProperties createProperties() {
- return new JavaBreakpointProperties();
- }
-
- @Nullable
- @Override
- public XBreakpointProperties createBreakpointProperties(@NotNull VirtualFile file, int line) {
- return new JavaBreakpointProperties();
- }
-
- @Nullable
- @Override
- public XBreakpointCustomPropertiesPanel<XLineBreakpoint<XBreakpointProperties>> createCustomRightPropertiesPanel(@NotNull Project project) {
- return new JavaBreakpointPropertiesPanel(project);
- }
-
-
-} \ No newline at end of file
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointProperties.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java
index e2f3202a0d46..daab63a93265 100644
--- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointProperties.java
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java
@@ -13,27 +13,36 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.java.debugger.breakpoints;
+package org.jetbrains.java.debugger.breakpoints.properties;
import com.intellij.debugger.InstanceFilter;
import com.intellij.ui.classFilter.ClassFilter;
+import com.intellij.util.xmlb.annotations.AbstractCollection;
+import com.intellij.util.xmlb.annotations.OptionTag;
+import com.intellij.util.xmlb.annotations.Tag;
import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
import org.jetbrains.annotations.Nullable;
/**
* @author egor
*/
-public class JavaBreakpointProperties extends XBreakpointProperties<JavaBreakpointProperties> {
+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;
+ @OptionTag("class-filters-enabled")
public boolean CLASS_FILTERS_ENABLED = false;
private ClassFilter[] myClassFilters;
private ClassFilter[] myClassExclusionFilters;
+ @OptionTag("instance-filters-enabled")
public boolean INSTANCE_FILTERS_ENABLED = false;
private InstanceFilter[] myInstanceFilters;
+ @Tag("instance-filters")
+ @AbstractCollection(surroundWithTag = false)
public InstanceFilter[] getInstanceFilters() {
return myInstanceFilters != null ? myInstanceFilters : InstanceFilter.EMPTY_ARRAY;
}
@@ -42,13 +51,15 @@ public class JavaBreakpointProperties extends XBreakpointProperties<JavaBreakpoi
myInstanceFilters = instanceFilters;
}
- protected void addInstanceFilter(long l) {
+ public void addInstanceFilter(long l) {
final InstanceFilter[] filters = new InstanceFilter[myInstanceFilters.length + 1];
System.arraycopy(myInstanceFilters, 0, filters, 0, myInstanceFilters.length);
filters[myInstanceFilters.length] = InstanceFilter.create(String.valueOf(l));
myInstanceFilters = filters;
}
+ @Tag("class-filters")
+ @AbstractCollection(surroundWithTag = false)
public final ClassFilter[] getClassFilters() {
return myClassFilters != null ? myClassFilters : ClassFilter.EMPTY_ARRAY;
}
@@ -57,6 +68,8 @@ public class JavaBreakpointProperties extends XBreakpointProperties<JavaBreakpoi
myClassFilters = classFilters;
}
+ @Tag("class-exclusion-filters")
+ @AbstractCollection(surroundWithTag = false)
public ClassFilter[] getClassExclusionFilters() {
return myClassExclusionFilters != null ? myClassExclusionFilters : ClassFilter.EMPTY_ARRAY;
}
@@ -67,20 +80,20 @@ public class JavaBreakpointProperties extends XBreakpointProperties<JavaBreakpoi
@Nullable
@Override
- public JavaBreakpointProperties getState() {
- return this;
+ public T getState() {
+ return (T)this;
}
@Override
- public void loadState(JavaBreakpointProperties state) {
+ public void loadState(T state) {
COUNT_FILTER_ENABLED = state.COUNT_FILTER_ENABLED;
COUNT_FILTER = state.COUNT_FILTER;
CLASS_FILTERS_ENABLED = state.CLASS_FILTERS_ENABLED;
- myClassFilters = state.myClassFilters;
- myClassExclusionFilters = state.myClassExclusionFilters;
+ myClassFilters = state.getClassFilters();
+ myClassExclusionFilters = state.getClassExclusionFilters();
INSTANCE_FILTERS_ENABLED = state.INSTANCE_FILTERS_ENABLED;
- myInstanceFilters = state.myInstanceFilters;
+ myInstanceFilters = state.getInstanceFilters();
}
}
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaExceptionBreakpointProperties.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaExceptionBreakpointProperties.java
new file mode 100644
index 000000000000..e3b893e926ee
--- /dev/null
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaExceptionBreakpointProperties.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.debugger.breakpoints.properties;
+
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author egor
+ */
+public class JavaExceptionBreakpointProperties extends JavaBreakpointProperties<JavaExceptionBreakpointProperties> {
+ public boolean NOTIFY_CAUGHT = true;
+ public boolean NOTIFY_UNCAUGHT = true;
+
+ @Attribute("class")
+ public String myQualifiedName;
+
+ @Attribute("package")
+ public String myPackageName;
+
+ public JavaExceptionBreakpointProperties(String qualifiedName, String packageName) {
+ myQualifiedName = qualifiedName;
+ myPackageName = packageName;
+ }
+
+ public JavaExceptionBreakpointProperties() {
+ }
+
+ @Nullable
+ @Override
+ public JavaExceptionBreakpointProperties getState() {
+ return this;
+ }
+
+ @Override
+ public void loadState(JavaExceptionBreakpointProperties state) {
+ super.loadState(state);
+
+ NOTIFY_CAUGHT = state.NOTIFY_CAUGHT;
+ NOTIFY_UNCAUGHT = state.NOTIFY_UNCAUGHT;
+ myQualifiedName = state.myQualifiedName;
+ myPackageName = state.myPackageName;
+ }
+}
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaFieldBreakpointProperties.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaFieldBreakpointProperties.java
new file mode 100644
index 000000000000..13b760e81428
--- /dev/null
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaFieldBreakpointProperties.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.debugger.breakpoints.properties;
+
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author egor
+ */
+public class JavaFieldBreakpointProperties extends JavaBreakpointProperties<JavaFieldBreakpointProperties> {
+ public boolean WATCH_MODIFICATION = true;
+ public boolean WATCH_ACCESS = false;
+
+ @Attribute("field")
+ public String myFieldName;
+
+ @Attribute("class")
+ public String myClassName;
+
+ public JavaFieldBreakpointProperties(String fieldName, String className) {
+ myFieldName = fieldName;
+ myClassName = className;
+ }
+
+ public JavaFieldBreakpointProperties() {
+ }
+
+ @Nullable
+ @Override
+ public JavaFieldBreakpointProperties getState() {
+ return this;
+ }
+
+ @Override
+ public void loadState(JavaFieldBreakpointProperties state) {
+ super.loadState(state);
+
+ WATCH_MODIFICATION = state.WATCH_MODIFICATION;
+ WATCH_ACCESS = state.WATCH_ACCESS;
+ myFieldName = state.myFieldName;
+ myClassName = state.myClassName;
+ }
+}
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaLineBreakpointProperties.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaLineBreakpointProperties.java
new file mode 100644
index 000000000000..9a892346ac04
--- /dev/null
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaLineBreakpointProperties.java
@@ -0,0 +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 org.jetbrains.java.debugger.breakpoints.properties;
+
+/**
+ * @author egor
+ */
+public class JavaLineBreakpointProperties extends JavaBreakpointProperties<JavaLineBreakpointProperties> {
+}
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaMethodBreakpointProperties.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaMethodBreakpointProperties.java
new file mode 100644
index 000000000000..9392b565645b
--- /dev/null
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaMethodBreakpointProperties.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.java.debugger.breakpoints.properties;
+
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author egor
+ */
+public class JavaMethodBreakpointProperties extends JavaBreakpointProperties<JavaMethodBreakpointProperties> {
+ @Attribute("class")
+ public String myClassPattern;
+
+ @Attribute("method")
+ public String myMethodName;
+
+ public boolean WATCH_ENTRY = true;
+ public boolean WATCH_EXIT = true;
+
+ public JavaMethodBreakpointProperties(String classPattern, String methodName) {
+ myClassPattern = classPattern;
+ myMethodName = methodName;
+ }
+
+ public JavaMethodBreakpointProperties() {
+ }
+
+ @Nullable
+ @Override
+ public JavaMethodBreakpointProperties getState() {
+ return this;
+ }
+
+ @Override
+ public void loadState(JavaMethodBreakpointProperties state) {
+ super.loadState(state);
+
+ myClassPattern = state.myClassPattern;
+ myMethodName = state.myMethodName;
+
+ WATCH_ENTRY = state.WATCH_ENTRY;
+ WATCH_EXIT = state.WATCH_EXIT;
+ }
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/PositionManagerEx.java b/java/debugger/openapi/src/com/intellij/debugger/PositionManagerEx.java
new file mode 100644
index 000000000000..c1faee1f763f
--- /dev/null
+++ b/java/debugger/openapi/src/com/intellij/debugger/PositionManagerEx.java
@@ -0,0 +1,26 @@
+/*
+ * 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.debugger;
+
+import com.intellij.xdebugger.frame.XStackFrame;
+import com.sun.jdi.Location;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class PositionManagerEx implements PositionManager {
+ @Nullable
+ public abstract XStackFrame createStackFrame(@NotNull Location location);
+}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java b/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java
index 66fea2d7f38c..43c7fd47f02f 100644
--- a/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java
@@ -16,6 +16,7 @@
package com.intellij.debugger.engine;
import com.intellij.debugger.PositionManager;
+import com.intellij.debugger.PositionManagerEx;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
import com.intellij.debugger.engine.jdi.VirtualMachineProxy;
@@ -44,7 +45,7 @@ public interface DebugProcess {
RequestManager getRequestsManager();
- PositionManager getPositionManager();
+ PositionManagerEx getPositionManager();
VirtualMachineProxy getVirtualMachineProxy();
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java b/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java
index 1697684b9d21..b200e0ef1829 100644
--- a/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java
@@ -80,6 +80,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager {
return myStratumId;
}
+ @Override
public SourcePosition getSourcePosition(final Location location) throws NoDataException {
SourcePosition sourcePosition = null;
@@ -110,6 +111,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager {
return location.lineNumber(myStratumId);
}
+ @Override
@NotNull
public List<ReferenceType> getAllClasses(SourcePosition classPosition) throws NoDataException {
checkSourcePositionFileType(classPosition);
@@ -138,6 +140,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager {
}
}
+ @Override
@NotNull
public List<Location> locationsOfLine(final ReferenceType type, final SourcePosition position) throws NoDataException {
List<Location> locations = locationsOfClassAt(type, position);
@@ -149,6 +152,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager {
checkSourcePositionFileType(position);
return ApplicationManager.getApplication().runReadAction(new Computable<List<Location>>() {
+ @Override
public List<Location> compute() {
try {
final List<String> relativePaths = getRelativeSourePathsByType(type);
@@ -165,7 +169,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager {
}
catch(ClassNotPreparedException ignored) {
}
- catch (InternalError e) {
+ catch (InternalError ignored) {
myDebugProcess.getExecutionResult().getProcessHandler().notifyTextAvailable(
DebuggerBundle.message("internal.error.locations.of.line", type.name()), ProcessOutputTypes.SYSTEM);
}
@@ -176,7 +180,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager {
// This is needed because some servers (e.g. WebSphere) put not exact file name such as 'A.jsp '
private String getSourceName(final String name, final ReferenceType type) throws AbsentInformationException {
for(String sourceNameFromType: type.sourceNames(myStratumId)) {
- if (sourceNameFromType.indexOf(name) >= 0) {
+ if (sourceNameFromType.contains(name)) {
return sourceNameFromType;
}
}
@@ -199,11 +203,13 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager {
return type.locationsOfLine(myStratumId, fileName, lineNumber);
}
+ @Override
public ClassPrepareRequest createPrepareRequest(final ClassPrepareRequestor requestor, final SourcePosition position)
throws NoDataException {
checkSourcePositionFileType(position);
return myDebugProcess.getRequestsManager().createClassPrepareRequest(new ClassPrepareRequestor() {
+ @Override
public void processClassPrepare(DebugProcess debuggerProcess, ReferenceType referenceType) {
onClassPrepare(debuggerProcess, referenceType, position, requestor);
}
@@ -217,7 +223,7 @@ public abstract class JSR45PositionManager<Scope> implements PositionManager {
requestor.processClassPrepare(debuggerProcess, referenceType);
}
}
- catch (NoDataException e) {
+ catch (NoDataException ignored) {
}
}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java
index 7e0b6ee007f1..511b1af39daf 100644
--- a/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/StackFrameProxy.java
@@ -19,6 +19,7 @@ import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.sun.jdi.ClassLoaderReference;
import com.sun.jdi.Location;
import com.sun.jdi.StackFrame;
+import org.jetbrains.annotations.Nullable;
public interface StackFrameProxy extends ObjectReferenceProxy{
StackFrame getStackFrame() throws EvaluateException;
@@ -27,6 +28,7 @@ public interface StackFrameProxy extends ObjectReferenceProxy{
VirtualMachineProxy getVirtualMachine();
+ @Nullable
Location location() throws EvaluateException;
ClassLoaderReference getClassLoader() throws EvaluateException;
diff --git a/java/idea-ui/src/com/intellij/ide/impl/ProjectStructureSelectInTarget.java b/java/idea-ui/src/com/intellij/ide/impl/ProjectStructureSelectInTarget.java
index d282c684e3db..70457eb6bdf3 100644
--- a/java/idea-ui/src/com/intellij/ide/impl/ProjectStructureSelectInTarget.java
+++ b/java/idea-ui/src/com/intellij/ide/impl/ProjectStructureSelectInTarget.java
@@ -18,6 +18,7 @@ package com.intellij.ide.impl;
import com.intellij.facet.*;
import com.intellij.ide.*;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.DumbAware;
@@ -48,7 +49,8 @@ public class ProjectStructureSelectInTarget extends SelectInTargetBase implement
final Object o = ((WrappingVirtualFile)file).getWrappedObject(context.getProject());
return o instanceof Facet;
}
- return fileIndex.isInContent(file) || fileIndex.isInLibraryClasses(file) || fileIndex.isInLibrarySource(file);
+ return fileIndex.isInContent(file) || fileIndex.isInLibraryClasses(file) || fileIndex.isInLibrarySource(file)
+ || StdFileTypes.IDEA_MODULE.equals(file.getFileType()) && findModuleByModuleFile(context.getProject(), file) != null;
}
@Override
@@ -64,8 +66,9 @@ public class ProjectStructureSelectInTarget extends SelectInTargetBase implement
module = facet == null? null : facet.getModule();
}
else {
+ Module moduleByIml = file.getFileType().equals(StdFileTypes.IDEA_MODULE) ? findModuleByModuleFile(project, file) : null;
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
- module = fileIndex.getModuleForFile(file);
+ module = moduleByIml != null ? moduleByIml : fileIndex.getModuleForFile(file);
facet = fileIndex.isInSourceContent(file) ? null : findFacet(project, file);
}
if (module != null || facet != null) {
@@ -95,6 +98,16 @@ public class ProjectStructureSelectInTarget extends SelectInTargetBase implement
}
@Nullable
+ private static Module findModuleByModuleFile(@NotNull Project project, @NotNull VirtualFile file) {
+ for (Module module : ModuleManager.getInstance(project).getModules()) {
+ if (file.equals(module.getModuleFile())) {
+ return module;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
private static Facet findFacet(final @NotNull Project project, final @NotNull VirtualFile file) {
for (FacetTypeId id : FacetTypeRegistry.getInstance().getFacetTypeIds()) {
if (hasFacetWithRoots(project, id)) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
index 324a222a018d..72ad0f26efa1 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
@@ -406,8 +406,9 @@ public class GenericsHighlightUtil {
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && aClass.isInterface() && method.hasModifierProperty(PsiModifier.DEFAULT)) {
HierarchicalMethodSignature sig = method.getHierarchicalMethodSignature();
for (HierarchicalMethodSignature methodSignature : sig.getSuperSignatures()) {
- final PsiClass containingClass = methodSignature.getMethod().getContainingClass();
- if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) {
+ final PsiMethod objectMethod = methodSignature.getMethod();
+ final PsiClass containingClass = objectMethod.getContainingClass();
+ if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) && objectMethod.hasModifierProperty(PsiModifier.PUBLIC)) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.descriptionAndTooltip("Default method '" + sig.getName() + "' overrides a member of 'java.lang.Object'")
.range(methodIdentifier)
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
index 4e9d79fecf57..352e74557eed 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
@@ -1324,8 +1324,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
myHolder.add(GenericsHighlightUtil.checkParametersAllowed(list, myLanguageLevel,myFile));
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParametersOnRaw(list));
if (!myHolder.hasErrorResults()) {
- for (PsiType type : list.getTypeArguments()) {
- myHolder.add(HighlightUtil.checkDiamondFeature(type, list, myLanguageLevel,myFile));
+ for (PsiTypeElement typeElement : list.getTypeParameterElements()) {
+ myHolder.add(HighlightUtil.checkDiamondFeature(typeElement.getType(), list, myLanguageLevel,myFile));
}
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java
index b9c5d21bcd5e..a5104f1deb51 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.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.
@@ -33,10 +33,11 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import static com.intellij.util.ObjectUtils.assertNotNull;
+
public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement {
private final PsiType myType;
@@ -75,28 +76,26 @@ public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement
addTypeCast(project, (PsiExpression)startElement, myType);
}
- private static void addTypeCast(Project project, PsiExpression originalExpression, PsiType type) throws IncorrectOperationException {
+ private static void addTypeCast(Project project, PsiExpression originalExpression, PsiType type) {
PsiExpression typeCast = createCastExpression(originalExpression, project, type);
originalExpression.replace(typeCast);
}
- static PsiExpression createCastExpression(PsiExpression originalExpression, Project project, PsiType type) throws IncorrectOperationException {
+ static PsiExpression createCastExpression(PsiExpression originalExpression, Project project, PsiType type) {
// remove nested casts
- PsiElement element = PsiUtil.deparenthesizeExpression(originalExpression);
- if (element == null){
- return null;
- }
- PsiElementFactory factory = JavaPsiFacade.getInstance(originalExpression.getProject()).getElementFactory();
+ PsiElement expression = PsiUtil.deparenthesizeExpression(originalExpression);
+ if (expression == null) return null;
+ PsiElementFactory factory = JavaPsiFacade.getInstance(originalExpression.getProject()).getElementFactory();
PsiTypeCastExpression typeCast = (PsiTypeCastExpression)factory.createExpressionFromText("(Type)value", null);
+ assertNotNull(typeCast.getCastType()).replace(factory.createTypeElement(type));
typeCast = (PsiTypeCastExpression)CodeStyleManager.getInstance(project).reformat(typeCast);
- typeCast.getCastType().replace(factory.createTypeElement(type));
- if (element instanceof PsiConditionalExpression) {
- // we'd better cast one branch of ternary expression if we could
- PsiConditionalExpression expression = (PsiConditionalExpression)element.copy();
- PsiExpression thenE = expression.getThenExpression();
- PsiExpression elseE = expression.getElseExpression();
+ if (expression instanceof PsiConditionalExpression) {
+ // we'd better cast one branch of ternary expression if we can
+ PsiConditionalExpression conditional = (PsiConditionalExpression)expression.copy();
+ PsiExpression thenE = conditional.getThenExpression();
+ PsiExpression elseE = conditional.getElseExpression();
PsiType thenType = thenE == null ? null : thenE.getType();
PsiType elseType = elseE == null ? null : elseE.getType();
if (elseType != null && thenType != null) {
@@ -104,18 +103,20 @@ public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement
boolean replaceElse = !TypeConversionUtil.isAssignable(type, elseType);
if (replaceThen != replaceElse) {
if (replaceThen) {
- typeCast.getOperand().replace(thenE);
+ assertNotNull(typeCast.getOperand()).replace(thenE);
thenE.replace(typeCast);
}
else {
- typeCast.getOperand().replace(elseE);
+ assertNotNull(typeCast.getOperand()).replace(elseE);
elseE.replace(typeCast);
}
- return expression;
+ return conditional;
}
}
}
- typeCast.getOperand().replace(element);
+
+ assertNotNull(typeCast.getOperand()).replace(expression);
+
return typeCast;
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java
index 76580adaa5f4..b4a8d5b99d17 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.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,14 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/**
- * Created by IntelliJ IDEA.
- * User: cdr
- * Date: Nov 13, 2002
- * Time: 3:26:50 PM
- * To change this template use Options | File Templates.
- */
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.FileModificationService;
@@ -32,6 +24,7 @@ import com.intellij.openapi.editor.Editor;
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.impl.source.resolve.DefaultParameterTypeInferencePolicy;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
@@ -39,11 +32,18 @@ import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import static com.intellij.util.ObjectUtils.assertNotNull;
+
+/**
+ * @author cdr
+ * @since Nov 13, 2002
+ */
public class ChangeTypeArgumentsFix implements IntentionAction, HighPriorityAction {
+ private static final Logger LOG = Logger.getInstance("#" + ChangeTypeArgumentsFix.class.getName());
+
private final PsiMethod myTargetMethod;
private final PsiClass myPsiClass;
private final PsiExpression[] myExpressions;
- private static final Logger LOG = Logger.getInstance("#" + ChangeTypeArgumentsFix.class.getName());
private final PsiNewExpression myNewExpression;
ChangeTypeArgumentsFix(@NotNull PsiMethod targetMethod,
@@ -116,11 +116,12 @@ public class ChangeTypeArgumentsFix implements IntentionAction, HighPriorityActi
LOG.assertTrue(reference != null, myNewExpression);
final PsiReferenceParameterList parameterList = reference.getParameterList();
LOG.assertTrue(parameterList != null, myNewExpression);
+ PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
PsiTypeElement[] elements = parameterList.getTypeParameterElements();
for (int i = elements.length - 1; i >= 0; i--) {
- PsiTypeElement typeElement = elements[i];
- final PsiType typeArg = psiSubstitutor.substitute(typeParameters[i]);
- typeElement.replace(JavaPsiFacade.getElementFactory(project).createTypeElement(typeArg));
+ PsiType typeArg = assertNotNull(psiSubstitutor.substitute(typeParameters[i]));
+ PsiElement replaced = elements[i].replace(factory.createTypeElement(typeArg));
+ JavaCodeStyleManager.getInstance(file.getProject()).shortenClassReferences(replaced);
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java
index 987f02dc9c39..84f704f64dcd 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java
@@ -64,15 +64,25 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement {
}
@Nullable
- public static PsiModifierListOwner getContainer(final PsiElement element) {
- PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(element, PsiParameter.class, false);
- if (listOwner == null) {
- final PsiIdentifier psiIdentifier = PsiTreeUtil.getParentOfType(element, PsiIdentifier.class, false);
- if (psiIdentifier != null && psiIdentifier.getParent() instanceof PsiModifierListOwner) {
- listOwner = (PsiModifierListOwner)psiIdentifier.getParent();
+ public static PsiModifierListOwner getContainer(final PsiFile file, int offset) {
+ PsiReference reference = file.findReferenceAt(offset);
+ if (reference != null) {
+ PsiElement target = reference.resolve();
+ if (target instanceof PsiMember) {
+ return (PsiMember)target;
}
}
- return listOwner;
+
+ PsiElement element = file.findElementAt(offset);
+
+ PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(element, PsiParameter.class, false);
+ if (listOwner != null) return listOwner;
+
+ final PsiIdentifier psiIdentifier = PsiTreeUtil.getParentOfType(element, PsiIdentifier.class, false);
+ if (psiIdentifier != null && psiIdentifier.getParent() instanceof PsiModifierListOwner) {
+ return (PsiModifierListOwner)psiIdentifier.getParent();
+ }
+ return null;
}
@Override
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
index 6684613f0ab0..272ce37708ad 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
@@ -41,7 +41,7 @@ public class AddNullableNotNullAnnotationFix extends AddAnnotationPsiFix {
if (!super.isAvailable(project, file, startElement, endElement)) {
return false;
}
- PsiModifierListOwner owner = getContainer(startElement);
+ PsiModifierListOwner owner = getContainer(file, startElement.getTextRange().getStartOffset());
if (owner == null || AnnotationUtil.isAnnotated(owner, getAnnotationsToRemove()[0], false, false)) {
return false;
}
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 ed3494096265..b89473e29b83 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java
@@ -22,6 +22,7 @@ import com.intellij.codeInsight.intention.HighPriorityAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -97,8 +98,11 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
final String localName = local.getName();
if (localName != null && helper.resolveReferencedVariable(localName, aClass) != null) return;
}
- holder.registerProblem(aClass.getBaseClassReference(), "Anonymous #ref #loc can be replaced with lambda",
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithLambdaFix());
+ final PsiElement lBrace = aClass.getLBrace();
+ LOG.assertTrue(lBrace != null);
+ final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent());
+ holder.registerProblem(aClass.getParent(), "Anonymous #ref #loc can be replaced with lambda",
+ ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithLambdaFix());
}
}
}
@@ -125,8 +129,8 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
- if (element != null) {
- final PsiAnonymousClass anonymousClass = PsiTreeUtil.getParentOfType(element, PsiAnonymousClass.class);
+ if (element instanceof PsiNewExpression) {
+ final PsiAnonymousClass anonymousClass = ((PsiNewExpression)element).getAnonymousClass();
LOG.assertTrue(anonymousClass != null);
ChangeContextUtil.encodeContextInfo(anonymousClass, true);
final PsiElement lambdaContext = anonymousClass.getParent().getParent();
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java
index 6ad6d223b5a0..6eec61428cda 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java
@@ -18,10 +18,10 @@ package com.intellij.codeInspection;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.RedundantCastUtil;
import org.jetbrains.annotations.Nls;
@@ -79,8 +79,11 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI
if (parent instanceof PsiNewExpression) {
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)parent).getClassOrAnonymousClassReference();
if (classReference != null) {
- holder.registerProblem(classReference,
- "Anonymous #ref #loc can be replaced with method reference", new ReplaceWithMethodRefFix());
+ final PsiElement lBrace = aClass.getLBrace();
+ LOG.assertTrue(lBrace != null);
+ final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent());
+ holder.registerProblem(parent,
+ "Anonymous #ref #loc can be replaced with method reference", ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithMethodRefFix());
}
}
}
@@ -107,29 +110,31 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
- final PsiAnonymousClass anonymousClass = PsiTreeUtil.getParentOfType(element, PsiAnonymousClass.class);
- if (anonymousClass == null) return;
- final PsiMethod[] methods = anonymousClass.getMethods();
- if (methods.length != 1) return;
+ if (element instanceof PsiNewExpression) {
+ final PsiAnonymousClass anonymousClass = ((PsiNewExpression)element).getAnonymousClass();
+ if (anonymousClass == null) return;
+ final PsiMethod[] methods = anonymousClass.getMethods();
+ if (methods.length != 1) return;
- final PsiParameter[] parameters = methods[0].getParameterList().getParameters();
- final PsiCallExpression callExpression = LambdaCanBeMethodReferenceInspection
- .canBeMethodReferenceProblem(methods[0].getBody(), parameters, anonymousClass.getBaseClassType());
- if (callExpression == null) return;
- final String methodRefText =
- LambdaCanBeMethodReferenceInspection.createMethodReferenceText(callExpression, anonymousClass.getBaseClassType(), parameters);
+ final PsiParameter[] parameters = methods[0].getParameterList().getParameters();
+ final PsiCallExpression callExpression = LambdaCanBeMethodReferenceInspection
+ .canBeMethodReferenceProblem(methods[0].getBody(), parameters, anonymousClass.getBaseClassType());
+ if (callExpression == null) return;
+ final String methodRefText =
+ LambdaCanBeMethodReferenceInspection.createMethodReferenceText(callExpression, anonymousClass.getBaseClassType(), parameters);
- if (methodRefText != null) {
- final String canonicalText = anonymousClass.getBaseClassType().getCanonicalText();
- final PsiExpression psiExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText("(" + canonicalText + ")" + methodRefText, anonymousClass);
-
- PsiElement castExpr = anonymousClass.getParent().replace(psiExpression);
- if (RedundantCastUtil.isCastRedundant((PsiTypeCastExpression)castExpr)) {
- final PsiExpression operand = ((PsiTypeCastExpression)castExpr).getOperand();
- LOG.assertTrue(operand != null);
- castExpr = castExpr.replace(operand);
+ if (methodRefText != null) {
+ final String canonicalText = anonymousClass.getBaseClassType().getCanonicalText();
+ final PsiExpression psiExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText("(" + canonicalText + ")" + methodRefText, anonymousClass);
+
+ PsiElement castExpr = anonymousClass.getParent().replace(psiExpression);
+ if (RedundantCastUtil.isCastRedundant((PsiTypeCastExpression)castExpr)) {
+ final PsiExpression operand = ((PsiTypeCastExpression)castExpr).getOperand();
+ LOG.assertTrue(operand != null);
+ castExpr = castExpr.replace(operand);
+ }
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(castExpr);
}
- JavaCodeStyleManager.getInstance(project).shortenClassReferences(castExpr);
}
}
}
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 8a8a6db0752e..9bc2a6ecacc2 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java
@@ -88,27 +88,7 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
protected static PsiCallExpression canBeMethodReferenceProblem(@Nullable final PsiElement body,
final PsiParameter[] parameters,
PsiType functionalInterfaceType) {
- PsiCallExpression methodCall = null;
- if (body instanceof PsiCallExpression) {
- methodCall = (PsiCallExpression)body;
- }
- else if (body instanceof PsiCodeBlock) {
- final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
- if (statements.length == 1) {
- if (statements[0] instanceof PsiReturnStatement) {
- final PsiExpression returnValue = ((PsiReturnStatement)statements[0]).getReturnValue();
- if (returnValue instanceof PsiCallExpression) {
- methodCall = (PsiCallExpression)returnValue;
- }
- }
- else if (statements[0] instanceof PsiExpressionStatement) {
- final PsiExpression expr = ((PsiExpressionStatement)statements[0]).getExpression();
- if (expr instanceof PsiCallExpression) {
- methodCall = (PsiCallExpression)expr;
- }
- }
- }
- }
+ PsiCallExpression methodCall = extractMethodCallFromBlock(body);
if (methodCall != null) {
final PsiExpressionList argumentList = methodCall.getArgumentList();
@@ -218,6 +198,40 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
return null;
}
+ public static PsiCallExpression extractMethodCallFromBlock(PsiElement body) {
+ PsiCallExpression methodCall = null;
+ if (body instanceof PsiCallExpression) {
+ methodCall = (PsiCallExpression)body;
+ }
+ else if (body instanceof PsiCodeBlock) {
+ final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
+ if (statements.length == 1) {
+ if (statements[0] instanceof PsiReturnStatement) {
+ final PsiExpression returnValue = ((PsiReturnStatement)statements[0]).getReturnValue();
+ if (returnValue instanceof PsiCallExpression) {
+ methodCall = (PsiCallExpression)returnValue;
+ }
+ }
+ else if (statements[0] instanceof PsiExpressionStatement) {
+ final PsiExpression expr = ((PsiExpressionStatement)statements[0]).getExpression();
+ if (expr instanceof PsiCallExpression) {
+ methodCall = (PsiCallExpression)expr;
+ }
+ }
+ }
+ }
+ else if (body instanceof PsiBlockStatement) {
+ return extractMethodCallFromBlock(((PsiBlockStatement)body).getCodeBlock());
+ }
+ else if (body instanceof PsiExpressionStatement) {
+ final PsiExpression expression = ((PsiExpressionStatement)body).getExpression();
+ if (expression instanceof PsiCallExpression) {
+ methodCall = (PsiCallExpression)expression;
+ }
+ }
+ return methodCall;
+ }
+
@Nullable
private static PsiMethod ensureNonAmbiguousMethod(PsiParameter[] parameters, @NotNull PsiMethod psiMethod) {
String methodName = psiMethod.getName();
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java
index 8101d16f5a1e..919fb4ea28db 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java
@@ -21,7 +21,9 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.controlFlow.*;
+import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
@@ -106,9 +108,14 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
}
});
- if (effectivelyFinal[0] && !isTrivial(body, statement.getIterationParameter(), iteratedValueType)) {
- holder.registerProblem(iteratedValue, "Can be replaced with foreach call",
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithForeachCallFix());
+ if (effectivelyFinal[0]) {
+ if (isCollectCall(body)) {
+ holder.registerProblem(iteratedValue, "Can be replaced with collect call",
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithCollectCallFix());
+ } else if (!isTrivial(body, statement.getIterationParameter(), iteratedValueType)) {
+ holder.registerProblem(iteratedValue, "Can be replaced with foreach call",
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithForeachCallFix());
+ }
}
}
}
@@ -121,10 +128,46 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
};
}
+ private static boolean isCollectCall(PsiStatement body) {
+ final PsiMethodCallExpression methodCallExpression = extractAddCall(body);
+ if (methodCallExpression != null) {
+ final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
+ final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
+ PsiClass qualifierClass = null;
+ if (qualifierExpression instanceof PsiReferenceExpression) {
+ qualifierClass = PsiUtil.resolveClassInType(qualifierExpression.getType());
+ } else if (qualifierExpression == null) {
+ final PsiClass enclosingClass = PsiTreeUtil.getParentOfType(body, PsiClass.class);
+ if (PsiUtil.getEnclosingStaticElement(body, enclosingClass) == null) {
+ qualifierClass = enclosingClass;
+ }
+ }
+
+ if (qualifierClass != null &&
+ InheritanceUtil.isInheritor(qualifierClass, false, CommonClassNames.JAVA_UTIL_COLLECTION)) {
+
+ final PsiElement resolve = methodExpression.resolve();
+ if (resolve instanceof PsiMethod &&
+ "add".equals(((PsiMethod)resolve).getName()) &&
+ ((PsiMethod)resolve).getParameterList().getParametersCount() == 1) {
+ final PsiExpression[] args = methodCallExpression.getArgumentList().getExpressions();
+ if (args.length == 1) {
+ if (args[0] instanceof PsiCallExpression) {
+ final PsiMethod method = ((PsiCallExpression)args[0]).resolveMethod();
+ return method != null && !method.hasTypeParameters();
+ }
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
private static boolean isTrivial(PsiStatement body, PsiParameter parameter, PsiType iteratedValueType) {
final PsiIfStatement ifStatement = extractIfStatement(body);
//stream
- if (ifStatement != null && ifStatement.getElseBranch() == null && ifStatement.getThenBranch() != null &&
+ if (ifStatement != null &&
InheritanceUtil.isInheritor(iteratedValueType, CommonClassNames.JAVA_UTIL_COLLECTION)) {
return false;
}
@@ -157,11 +200,12 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
String foreEachText = body.getText();
String iterated = iteratedValue.getText();
- if (ifStmt != null && ifStmt.getElseBranch() == null) {
+ if (ifStmt != null) {
final PsiExpression condition = ifStmt.getCondition();
if (condition != null) {
final PsiStatement thenBranch = ifStmt.getThenBranch();
- if (thenBranch != null && InheritanceUtil.isInheritor(iteratedValue.getType(), CommonClassNames.JAVA_UTIL_COLLECTION)) {
+ LOG.assertTrue(thenBranch != null);
+ if (InheritanceUtil.isInheritor(iteratedValue.getType(), CommonClassNames.JAVA_UTIL_COLLECTION)) {
body = thenBranch;
foreEachText = thenBranch.getText();
iterated += ".stream().filter(" + parameter.getName() + " -> " + condition.getText() +")";
@@ -170,8 +214,16 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
}
final PsiParameter[] parameters = {parameter};
- final PsiCallExpression expression = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem(body instanceof PsiBlockStatement ? ((PsiBlockStatement)body).getCodeBlock() : body, parameters, null);
- final String methodReferenceText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(expression, null, parameters);
+ String methodReferenceText = null;
+ final PsiCallExpression callExpression = LambdaCanBeMethodReferenceInspection.extractMethodCallFromBlock(body);
+ if (callExpression != null) {
+ final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
+ final PsiClass consumerClass = psiFacade.findClass("java.util.function.Consumer", GlobalSearchScope.allScope(project));
+ final PsiClassType functionalType = consumerClass != null ? psiFacade.getElementFactory().createType(consumerClass, callExpression.getType()) : null;
+
+ final PsiCallExpression toConvertCall = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem(body instanceof PsiBlockStatement ? ((PsiBlockStatement)body).getCodeBlock() : body, parameters, functionalType);
+ methodReferenceText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(toConvertCall, functionalType, parameters);
+ }
final String lambdaText = parameter.getName() + " -> " + foreEachText;
final String codeBlock8 = methodReferenceText != null ? methodReferenceText : lambdaText;
PsiExpressionStatement callStatement = (PsiExpressionStatement)JavaPsiFacade.getElementFactory(project).createStatementFromText(iterated + ".forEach(" + codeBlock8 + ");", foreachStatement);
@@ -191,6 +243,98 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
}
}
+ private static class ReplaceWithCollectCallFix implements LocalQuickFix {
+ @NotNull
+ @Override
+ public String getName() {
+ return getFamilyName();
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace with collect";
+ }
+
+ @Override
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ final PsiForeachStatement foreachStatement = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiForeachStatement.class);
+ if (foreachStatement != null) {
+ PsiStatement body = foreachStatement.getBody();
+ final PsiExpression iteratedValue = foreachStatement.getIteratedValue();
+ if (body != null && iteratedValue != null) {
+ final PsiParameter parameter = foreachStatement.getIterationParameter();
+
+ final PsiIfStatement ifStatement = extractIfStatement(body);
+ final PsiMethodCallExpression methodCallExpression = extractAddCall(body);
+ String iteration = iteratedValue.getText() + ".stream()";
+ if (ifStatement != null) {
+ final PsiExpression condition = ifStatement.getCondition();
+ if (condition != null) {
+ iteration += ".filter(" + parameter.getName() + " -> " + condition.getText() +")";
+ }
+ }
+ iteration +=".map(";
+
+ final PsiExpression mapperCall = methodCallExpression.getArgumentList().getExpressions()[0];
+
+ final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
+ final PsiClass functionClass = psiFacade.findClass("java.util.function.Function", GlobalSearchScope.allScope(project));
+ final PsiClassType functionalInterfaceType = functionClass != null ? psiFacade.getElementFactory().createType(functionClass, parameter.getType(), mapperCall.getType()) : null;
+ final PsiCallExpression toConvertCall = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem(mapperCall,
+ new PsiParameter[]{
+ parameter},
+ functionalInterfaceType);
+ final String methodReferenceText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(toConvertCall, functionalInterfaceType, new PsiParameter[]{parameter});
+ if (methodReferenceText != null) {
+ iteration += methodReferenceText;
+ } else {
+ iteration += parameter.getName() + " -> " + mapperCall.getText();
+ }
+ iteration += ").collect(java.util.stream.Collectors.";
+
+ String variableName = null;
+ PsiExpression initializer = null;
+ final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression();
+ if (qualifierExpression instanceof PsiReferenceExpression) {
+ final PsiElement resolve = ((PsiReferenceExpression)qualifierExpression).resolve();
+ if (resolve instanceof PsiVariable) {
+ if (resolve instanceof PsiLocalVariable && foreachStatement.equals(PsiTreeUtil.skipSiblingsForward(resolve.getParent(), PsiWhiteSpace.class))) {
+ initializer = ((PsiVariable)resolve).getInitializer();
+ }
+ variableName = ((PsiVariable)resolve).getName() + ".";
+ }
+ } else if (qualifierExpression == null) {
+ variableName = "";
+ }
+
+ PsiElement result = null;
+ if (initializer != null) {
+ final PsiType initializerType = initializer.getType();
+ final PsiClassType rawType = initializerType instanceof PsiClassType ? ((PsiClassType)initializerType).rawType() : null;
+ if (rawType != null && rawType.equalsToText(CommonClassNames.JAVA_UTIL_ARRAY_LIST)) {
+ iteration += "toList()";
+ } else if (rawType != null && rawType.equalsToText(CommonClassNames.JAVA_UTIL_HASH_SET)) {
+ iteration += "toSet()";
+ } else {
+ iteration += "toCollection(() -> " + initializer.getText() +")";
+ }
+ iteration += ")";
+ result = initializer.replace(JavaPsiFacade.getElementFactory(project).createExpressionFromText(iteration, foreachStatement));
+ foreachStatement.delete();
+ } else if (variableName != null){
+ iteration += "toList())";
+ result = foreachStatement.replace(JavaPsiFacade.getElementFactory(project).createStatementFromText(variableName + "addAll(" + iteration +");", foreachStatement));
+ }
+
+ if (result != null) {
+ result = JavaCodeStyleManager.getInstance(project).shortenClassReferences(result);
+ }
+ }
+ }
+ }
+ }
+
public static PsiIfStatement extractIfStatement(PsiStatement body) {
PsiIfStatement ifStmt = null;
if (body instanceof PsiIfStatement) {
@@ -201,6 +345,34 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
ifStmt = (PsiIfStatement)statements[0];
}
}
- return ifStmt;
+ if (ifStmt != null && ifStmt.getElseBranch() == null && ifStmt.getThenBranch() != null) {
+ return ifStmt;
+ }
+ return null;
+ }
+
+ private static PsiMethodCallExpression extractAddCall(PsiStatement body) {
+ final PsiIfStatement ifStatement = extractIfStatement(body);
+ if (ifStatement != null) {
+ return extractAddCall(ifStatement.getThenBranch());
+ }
+ PsiExpressionStatement stmt = null;
+ if (body instanceof PsiBlockStatement) {
+ final PsiStatement[] statements = ((PsiBlockStatement)body).getCodeBlock().getStatements();
+ if (statements.length == 1 && statements[0] instanceof PsiExpressionStatement) {
+ stmt = (PsiExpressionStatement)statements[0];
+ }
+ }
+ else if (body instanceof PsiExpressionStatement) {
+ stmt = (PsiExpressionStatement)body;
+ }
+
+ if (stmt != null) {
+ final PsiExpression expression = stmt.getExpression();
+ if (expression instanceof PsiMethodCallExpression) {
+ return (PsiMethodCallExpression)expression;
+ }
+ }
+ return null;
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
index cc1b2ae059cd..2e15ac48f7f3 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
@@ -506,12 +506,16 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
final String text = isNullLiteralExpression(expr)
? InspectionsBundle.message("dataflow.message.return.null.from.notnullable", presentableNullable)
: InspectionsBundle.message("dataflow.message.return.nullable.from.notnullable", presentableNullable);
- holder.registerProblem(expr, text, new AnnotateMethodFix(defaultNullable, ArrayUtil.toStringArray(manager.getNotNulls())){
- @Override
- public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) {
- return 1;
- }
- });
+ final LocalQuickFix[] fixes =
+ PsiTreeUtil.skipParentsOfType(expr, PsiCodeBlock.class, PsiReturnStatement.class) instanceof PsiLambdaExpression
+ ? LocalQuickFix.EMPTY_ARRAY
+ : new LocalQuickFix[]{ new AnnotateMethodFix(defaultNullable, ArrayUtil.toStringArray(manager.getNotNulls())) {
+ @Override
+ public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) {
+ return 1;
+ }
+ }};
+ holder.registerProblem(expr, text, fixes);
}
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java
index b647e7d1b37f..f8c395ce17fd 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java
@@ -81,6 +81,13 @@ public class JavaLineMarkerProvider implements LineMarkerProvider, DumbAware {
}
}
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(element);
+ if (interfaceMethod != null) {
+ final Icon icon = AllIcons.Gutter.ImplementingMethod;
+ final MarkerType type = MarkerType.OVERRIDING_METHOD;
+ return new ArrowUpLineMarkerInfo(element, icon, type);
+ }
+
if (myDaemonSettings.SHOW_METHOD_SEPARATORS && element.getFirstChild() == null) {
PsiElement element1 = element;
boolean isMember = false;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java
index 12b1788dcea7..72e8eca35fa6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java
@@ -53,27 +53,27 @@ public class MarkerType {
public static final MarkerType OVERRIDING_METHOD = new MarkerType(new NullableFunction<PsiElement, String>() {
@Override
public String fun(PsiElement element) {
- PsiElement parent = element.getParent();
+ PsiElement parent = getParentMethod(element);
if (!(parent instanceof PsiMethod)) return null;
PsiMethod method = (PsiMethod)parent;
- return calculateOverridingMethodTooltip(method);
+ return calculateOverridingMethodTooltip(method, method != element.getParent());
}
}, new LineMarkerNavigator(){
@Override
public void browse(MouseEvent e, PsiElement element) {
- PsiElement parent = element.getParent();
+ PsiElement parent = getParentMethod(element);
if (!(parent instanceof PsiMethod)) return;
PsiMethod method = (PsiMethod)parent;
- navigateToOverridingMethod(e, method);
+ navigateToOverridingMethod(e, method, method != element.getParent());
}
});
@Nullable
- public static String calculateOverridingMethodTooltip(PsiMethod method) {
- PsiMethod[] superMethods = method.findSuperMethods(false);
- if (superMethods.length == 0) return null;
+ public static String calculateOverridingMethodTooltip(PsiMethod method, boolean acceptSelf) {
+ PsiMethod[] superMethods = composeSuperMethods(method, acceptSelf);
+ if (superMethods == null) return null;
PsiMethod superMethod = superMethods[0];
boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
@@ -90,9 +90,9 @@ public class MarkerType {
return GutterIconTooltipHelper.composeText(superMethods, "", DaemonBundle.message(key));
}
- public static void navigateToOverridingMethod(MouseEvent e, PsiMethod method) {
- PsiMethod[] superMethods = method.findSuperMethods(false);
- if (superMethods.length == 0) return;
+ public static void navigateToOverridingMethod(MouseEvent e, PsiMethod method, boolean acceptSelf) {
+ PsiMethod[] superMethods = composeSuperMethods(method, acceptSelf);
+ if (superMethods == null) return;
boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature(superMethods);
PsiElementListNavigator.openTargets(e, superMethods,
DaemonBundle.message("navigation.title.super.method", method.getName()),
@@ -100,6 +100,22 @@ public class MarkerType {
new MethodCellRenderer(showMethodNames));
}
+ @Nullable
+ private static PsiMethod[] composeSuperMethods(PsiMethod method, boolean acceptSelf) {
+ PsiMethod[] superMethods = method.findSuperMethods(false);
+ if (acceptSelf) {
+ superMethods = ArrayUtil.prepend(method, superMethods);
+ }
+ if (superMethods.length == 0) return null;
+ return superMethods;
+ }
+
+ private static PsiElement getParentMethod(PsiElement element) {
+ final PsiElement parent = element.getParent();
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(element);
+ return interfaceMethod != null ? interfaceMethod : parent;
+ }
+
public static final String SEARCHING_FOR_OVERRIDING_METHODS = "Searching for overriding methods";
public static final MarkerType OVERRIDEN_METHOD = new MarkerType(new NullableFunction<PsiElement, String>() {
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToCatchFix.java
index ccb1c3c369e4..5d51949c1d6b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToCatchFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExceptionToCatchFix.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.
@@ -52,7 +52,9 @@ public class AddExceptionToCatchFix extends BaseIntentionAction {
PsiDocumentManager.getInstance(project).commitAllDocuments();
PsiElement element = findElement(file, offset);
- PsiTryStatement tryStatement = (PsiTryStatement) element.getParent();
+ if (element == null) return;
+
+ PsiTryStatement tryStatement = (PsiTryStatement)element.getParent();
List<PsiClassType> unhandledExceptions = new ArrayList<PsiClassType>(ExceptionUtil.collectUnhandledExceptions(element, null));
ExceptionUtil.sortExceptionsByHierarchy(unhandledExceptions);
@@ -86,7 +88,9 @@ public class AddExceptionToCatchFix extends BaseIntentionAction {
}
}
- private static PsiCodeBlock addCatchStatement(PsiTryStatement tryStatement, PsiClassType exceptionType, PsiFile file) throws IncorrectOperationException {
+ private static PsiCodeBlock addCatchStatement(PsiTryStatement tryStatement,
+ PsiClassType exceptionType,
+ PsiFile file) throws IncorrectOperationException {
PsiElementFactory factory = JavaPsiFacade.getInstance(tryStatement.getProject()).getElementFactory();
if (tryStatement.getTryBlock() == null) {
@@ -108,9 +112,12 @@ public class AddExceptionToCatchFix extends BaseIntentionAction {
}
PsiParameter[] parameters = tryStatement.getCatchBlockParameters();
- parameters[parameters.length - 1].getTypeElement().replace(factory.createTypeElement(exceptionType));
- PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks();
+ PsiTypeElement typeElement = parameters[parameters.length - 1].getTypeElement();
+ if (typeElement != null) {
+ JavaCodeStyleManager.getInstance(file.getProject()).shortenClassReferences(typeElement);
+ }
+ PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks();
return catchBlocks[catchBlocks.length - 1];
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java
index 19a4639a0689..69800e5616f7 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java
@@ -200,7 +200,7 @@ public class StaticImportMethodFix implements IntentionAction {
//do not show methods from default package
&& !((PsiJavaFile)file).getPackageName().isEmpty()
&& PsiUtil.isAccessible(file.getProject(), method, element, containingClass)) {
- if (method.isDeprecated()) {
+ if (isEffectivelyDeprecated(method)) {
deprecated.put(containingClass, method);
return processCondition();
}
@@ -209,6 +209,20 @@ public class StaticImportMethodFix implements IntentionAction {
return processCondition();
}
+ private boolean isEffectivelyDeprecated(PsiMethod method) {
+ if (method.isDeprecated()) {
+ return true;
+ }
+ PsiClass aClass = method.getContainingClass();
+ while (aClass != null) {
+ if (aClass.isDeprecated()) {
+ return true;
+ }
+ aClass = aClass.getContainingClass();
+ }
+ return false;
+ }
+
private boolean processCondition() {
return (applicableList.isEmpty() ? list : applicableList).size() + deprecated.size() < 50;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java
index e72756865767..0d822feff94c 100644
--- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java
@@ -21,7 +21,6 @@ import com.intellij.openapi.project.DumbAware;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.text.CharArrayUtil;
-import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -119,9 +118,9 @@ public class AnnotationParameterInfoHandler implements ParameterInfoHandler<PsiA
@NonNls StringBuilder buffer = new StringBuilder();
buffer.append(p.getReturnType().getPresentableText());
buffer.append(" ");
- int highlightStartOffset = XmlStringUtil.escapeString(buffer.toString()).length();
+ int highlightStartOffset = buffer.length();
buffer.append(p.getName());
- int highlightEndOffset = XmlStringUtil.escapeString(buffer.toString()).length();
+ int highlightEndOffset = buffer.length();
buffer.append("()");
if (p.getDefaultValue() != null) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java
index 5da27d9c18d3..b3918fd0fbe2 100644
--- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java
@@ -32,7 +32,6 @@ import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashSet;
-import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -393,7 +392,7 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
for (int j = 0; j < numParams; j++) {
PsiParameter param = parms[j];
- int startOffset = XmlStringUtil.escapeString(buffer.toString()).length();
+ int startOffset = buffer.length();
if (param.isValid()) {
PsiType paramType = param.getType();
@@ -411,7 +410,7 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
}
}
- int endOffset = XmlStringUtil.escapeString(buffer.toString()).length();
+ int endOffset = buffer.length();
if (j < numParams - 1) {
buffer.append(", ");
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 2b839b5dfcde..daf5aa5eac74 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
@@ -26,13 +26,11 @@ import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.intention.AddAnnotationFix;
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
-import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Editor;
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;
@@ -49,22 +47,11 @@ public abstract class AddAnnotationIntention extends BaseIntentionAction {
// include not in project files
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
- CaretModel caretModel = editor.getCaretModel();
- int position = caretModel.getOffset();
- PsiElement element = file.findElementAt(position);
- return element != null && isAvailable(project, element);
- }
-
- public boolean isAvailable(@NotNull final Project project, @NotNull final PsiElement element) {
- if (!element.isValid()) return false;
- final PsiModifierListOwner owner;
- if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) {
- owner = AddAnnotationPsiFix.getContainer(element);
- }
- else {
+ final PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(file, editor.getCaretModel().getOffset());
+ if (owner == null ||
+ owner.getManager().isInProject(owner) && !CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) {
return false;
}
- if (owner == null) return false;
Pair<String, String[]> annotations = getAnnotations(project);
String toAdd = annotations.first;
String[] toRemove = annotations.second;
@@ -82,11 +69,7 @@ public abstract class AddAnnotationIntention extends BaseIntentionAction {
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
- CaretModel caretModel = editor.getCaretModel();
- int position = caretModel.getOffset();
- PsiElement element = file.findElementAt(position);
-
- PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(element);
+ PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(file, editor.getCaretModel().getOffset());
if (owner == null || !owner.isValid()) return;
Pair<String, String[]> annotations = getAnnotations(project);
String toAdd = annotations.first;
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseColorIntentionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseColorIntentionAction.java
index adde45b86af6..f3c9df9dfe16 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseColorIntentionAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseColorIntentionAction.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.
@@ -28,9 +28,11 @@ import static com.intellij.patterns.PlatformPatterns.psiElement;
/**
* @author Danila Ponomarenko
+ * @author Konstantin Bulenkov
*/
public abstract class BaseColorIntentionAction extends PsiElementBaseIntentionAction implements HighPriorityAction {
protected static final String JAVA_AWT_COLOR = "java.awt.Color";
+ protected static final String COLOR_UI_RESOURCE = "javax.swing.plaf.ColorUIResource";
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
@@ -39,29 +41,28 @@ public abstract class BaseColorIntentionAction extends PsiElementBaseIntentionAc
}
final PsiNewExpression expression = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class, false);
- if (expression == null) {
- return false;
- }
-
- return isJavaAwtColor(expression.getClassOrAnonymousClassReference()) && isValueArguments(expression.getArgumentList());
+ return expression != null
+ && isJavaAwtColor(expression.getClassOrAnonymousClassReference())
+ && isValueArguments(expression.getArgumentList());
}
private static boolean isJavaAwtColor(@Nullable PsiJavaCodeReferenceElement ref) {
- if (ref == null) {
- return false;
- }
-
- final PsiReference reference = ref.getReference();
- if (reference == null) {
- return false;
- }
+ final String fqn = getFqn(ref);
+ return JAVA_AWT_COLOR.equals(fqn) || COLOR_UI_RESOURCE.equals(fqn);
+ }
- final PsiElement psiElement = reference.resolve();
- if (psiElement instanceof PsiClass && JAVA_AWT_COLOR.equals(((PsiClass)psiElement).getQualifiedName())) {
- return true;
+ @Nullable
+ protected static String getFqn(@Nullable PsiJavaCodeReferenceElement ref) {
+ if (ref != null) {
+ final PsiReference reference = ref.getReference();
+ if (reference != null) {
+ final PsiElement psiElement = reference.resolve();
+ if (psiElement instanceof PsiClass) {
+ return ((PsiClass)psiElement).getQualifiedName();
+ }
+ }
}
-
- return false;
+ return null;
}
private static boolean isValueArguments(@Nullable PsiExpressionList arguments) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ColorChooserIntentionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ColorChooserIntentionAction.java
index db93d4e851f5..f5d1b3a28afe 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ColorChooserIntentionAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ColorChooserIntentionAction.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.
@@ -191,7 +191,7 @@ public class ColorChooserIntentionAction extends BaseColorIntentionAction {
final PsiManager manager = expression.getManager();
final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
final PsiExpression newCall = factory.createExpressionFromText(
- "new " + JAVA_AWT_COLOR + "("
+ "new " + getFqn(expression.getClassOrAnonymousClassReference()) + "("
+ color.getRed() + ", "
+ color.getGreen() + ", "
+ color.getBlue()
diff --git a/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java b/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java
index 94ddb7ae863e..55d82a987001 100644
--- a/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java
@@ -30,6 +30,7 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.FindSuperElementsHelper;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -65,20 +66,27 @@ public class JavaGotoSuperHandler implements CodeInsightActionHandler {
@Nullable
private PsiElement[] findSuperElements(PsiFile file, int offset) {
- PsiNameIdentifierOwner parent = getElement(file, offset);
- if (parent == null) return null;
+ PsiElement element = getElement(file, offset);
+ if (element == null) return null;
+
+ final PsiExpression expression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class, PsiMethodReferenceExpression.class);
+ if (expression != null) {
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(expression);
+ if (interfaceMethod != null) {
+ return ArrayUtil.prepend(interfaceMethod, interfaceMethod.findSuperMethods(false));
+ }
+ }
+
+ final PsiNameIdentifierOwner parent = PsiTreeUtil.getNonStrictParentOfType(element, PsiMethod.class, PsiClass.class);
+ if (parent == null) {
+ return null;
+ }
return FindSuperElementsHelper.findSuperElements(parent);
}
- protected PsiNameIdentifierOwner getElement(PsiFile file, int offset) {
- PsiElement element = file.findElementAt(offset);
- if (element == null) return null;
-
- PsiNameIdentifierOwner parent = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiClass.class);
- if (parent == null)
- return null;
- return parent;
+ protected PsiElement getElement(PsiFile file, int offset) {
+ return file.findElementAt(offset);
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java
index 7040347c4d0e..767077b3448e 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java
+++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java
@@ -28,7 +28,6 @@ import com.intellij.openapi.ui.InputValidatorEx;
import com.intellij.openapi.ui.Messages;
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.Contract;
import org.jetbrains.annotations.NotNull;
@@ -48,22 +47,15 @@ public class EditContractIntention extends BaseIntentionAction {
@Nullable
private static PsiMethod getTargetMethod(@NotNull Project project, Editor editor, PsiFile file) {
- PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
- if (element == null) return null;
- if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) {
- final PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(element);
- if (owner instanceof PsiMethod) {
- PsiElement original = owner.getOriginalElement();
- if (original instanceof PsiMethod) {
- return (PsiMethod)original;
- }
- return (PsiMethod)owner;
- }
+ final PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(file, editor.getCaretModel().getOffset());
+ if (owner instanceof PsiMethod &&
+ (!owner.getManager().isInProject(owner) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS)) {
+ PsiElement original = owner.getOriginalElement();
+ return original instanceof PsiMethod ? (PsiMethod)original : (PsiMethod)owner;
}
return null;
}
-
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
final PsiMethod method = getTargetMethod(project, editor, file);
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java
index db020ad58b8b..42d3098b7b07 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaReferenceAdjuster.java
@@ -60,6 +60,12 @@ public class JavaReferenceAdjuster implements ReferenceAdjuster {
}
if (rightKind) {
+ // annotations may jump out of reference (see PsiJavaCodeReferenceImpl#setAnnotations()) so they should be processed first
+ List<PsiAnnotation> annotations = PsiTreeUtil.getChildrenOfTypeAsList(ref, PsiAnnotation.class);
+ for (PsiAnnotation annotation : annotations) {
+ process(annotation.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode);
+ }
+
boolean isInsideDocComment = TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null;
boolean isShort = !ref.isQualified();
if (isInsideDocComment ? !useFqInJavadoc : !useFqInCode) {
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.java
index c184775ad11b..dbcbfdc4e546 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.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.
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -44,27 +45,29 @@ public class JavaClassReferenceSet {
private final int myStartInElement;
private final JavaClassReferenceProvider myProvider;
- public JavaClassReferenceSet(String str, PsiElement element, int startInElement, final boolean isStatic, JavaClassReferenceProvider provider) {
+ public JavaClassReferenceSet(@NotNull String str, @NotNull PsiElement element, int startInElement, final boolean isStatic, @NotNull JavaClassReferenceProvider provider) {
this(str, element, startInElement, isStatic, provider, null);
}
- private JavaClassReferenceSet(String str, PsiElement element, int startInElement, final boolean isStatic, JavaClassReferenceProvider provider,
+ private JavaClassReferenceSet(@NotNull String str, @NotNull PsiElement element, int startInElement, final boolean isStatic, @NotNull JavaClassReferenceProvider provider,
JavaClassReferenceSet context) {
myStartInElement = startInElement;
myProvider = provider;
reparse(str, element, isStatic, context);
}
+ @NotNull
public JavaClassReferenceProvider getProvider() {
return myProvider;
}
+ @NotNull
public TextRange getRangeInElement() {
PsiReference[] references = getReferences();
return new TextRange(references[0].getRangeInElement().getStartOffset(), references[references.length - 1].getRangeInElement().getEndOffset());
}
- private void reparse(String str, PsiElement element, final boolean isStaticImport, JavaClassReferenceSet context) {
+ private void reparse(@NotNull String str, @NotNull PsiElement element, final boolean isStaticImport, JavaClassReferenceSet context) {
myElement = element;
myContext = context;
final List<JavaClassReference> referencesList = new ArrayList<JavaClassReference>();
@@ -186,7 +189,8 @@ public class JavaClassReferenceSet {
myReferences = referencesList.toArray(new JavaClassReference[referencesList.size()]);
}
- protected JavaClassReference createReference(final int referenceIndex, final String subreferenceText, final TextRange textRange,
+ @NotNull
+ protected JavaClassReference createReference(final int referenceIndex, @NotNull String subreferenceText, @NotNull TextRange textRange,
final boolean staticImport) {
return new JavaClassReference(this, textRange, referenceIndex, subreferenceText, staticImport);
}
@@ -200,7 +204,7 @@ public class JavaClassReferenceSet {
return isAllowDollarInNames() ? c == DOLLAR : c == DOT;
}
- public void reparse(PsiElement element, final TextRange range) {
+ public void reparse(@NotNull PsiElement element, @NotNull TextRange range) {
final String text = range.substring(element.getText());
reparse(text, element, false, myContext);
}
@@ -209,6 +213,7 @@ public class JavaClassReferenceSet {
return myReferences[index];
}
+ @NotNull
public JavaClassReference[] getAllReferences() {
JavaClassReference[] result = myReferences;
if (myNestedGenericParameterReferences != null) {
@@ -229,10 +234,12 @@ public class JavaClassReferenceSet {
return myProvider.isSoft();
}
+ @NotNull
public PsiElement getElement() {
return myElement;
}
+ @NotNull
public PsiReference[] getReferences() {
return myReferences;
}
@@ -243,6 +250,7 @@ public class JavaClassReferenceSet {
}
@SuppressWarnings({"UnresolvedPropertyKey"})
+ @NotNull
public String getUnresolvedMessagePattern(int index){
if (canReferencePackage(index)) {
return JavaErrorMessages.message("error.cannot.resolve.class.or.package");
diff --git a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java
index ee207fb89fc7..a32dc464f7fa 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.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.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiUtil;
@@ -187,27 +188,28 @@ public class ChangeClassSignatureProcessor extends BaseRefactoringProcessor {
ChangeSignatureUtil.synchronizeList(myClass.getTypeParameterList(), newTypeParameters, TypeParameterList.INSTANCE, toRemoveParms);
}
- private boolean[] detectRemovedParameters(final PsiTypeParameter[] originaltypeParameters) {
- final boolean[] toRemoveParms = new boolean[originaltypeParameters.length];
- Arrays.fill(toRemoveParms, true);
+ private boolean[] detectRemovedParameters(final PsiTypeParameter[] original) {
+ final boolean[] toRemove = new boolean[original.length];
+ Arrays.fill(toRemove, true);
for (final TypeParameterInfo info : myNewSignature) {
int oldParameterIndex = info.getOldParameterIndex();
if (oldParameterIndex >= 0) {
- toRemoveParms[oldParameterIndex] = false;
+ toRemove[oldParameterIndex] = false;
}
}
- return toRemoveParms;
+ return toRemove;
}
- private void processUsage(final UsageInfo usage, final PsiTypeParameter[] originalTypeParameters, final boolean[] toRemoveParms)
- throws IncorrectOperationException {
+ private void processUsage(UsageInfo usage, PsiTypeParameter[] original, boolean[] toRemove) throws IncorrectOperationException {
PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)usage.getElement();
+ assert referenceElement != null : usage;
PsiSubstitutor usageSubstitutor = determineUsageSubstitutor(referenceElement);
PsiReferenceParameterList referenceParameterList = referenceElement.getParameterList();
+ assert referenceParameterList != null : referenceElement;
PsiTypeElement[] oldValues = referenceParameterList.getTypeParameterElements();
- if (oldValues.length != originalTypeParameters.length) return;
+ if (oldValues.length != original.length) return;
List<PsiTypeElement> newValues = new ArrayList<PsiTypeElement>();
for (final TypeParameterInfo info : myNewSignature) {
int oldIndex = info.getOldParameterIndex();
@@ -221,7 +223,9 @@ public class ChangeClassSignatureProcessor extends BaseRefactoringProcessor {
newValues.add(newValue);
}
}
- ChangeSignatureUtil.synchronizeList(referenceParameterList, newValues, ReferenceParameterList.INSTANCE, toRemoveParms);
+
+ ChangeSignatureUtil.synchronizeList(referenceParameterList, newValues, ReferenceParameterList.INSTANCE, toRemove);
+ JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(referenceParameterList);
}
private PsiSubstitutor determineUsageSubstitutor(PsiJavaCodeReferenceElement referenceElement) {
diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.java
index aa27a6e024ca..69fc99031e80 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.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.
@@ -33,11 +33,13 @@ import java.util.ArrayList;
import java.util.List;
public class ParameterInfoImpl implements JavaParameterInfo {
+ public static final ParameterInfoImpl[] EMPTY_ARRAY = {};
+
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ParameterInfoImpl");
+
public int oldParameterIndex;
- boolean useAnySingleVariable;
+ private boolean useAnySingleVariable;
private String name = "";
- public static final ParameterInfoImpl[] EMPTY_ARRAY = new ParameterInfoImpl[0];
private CanonicalTypes.Type myType;
String defaultValue = "";
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassProcessor.java
index 25a9481259d8..2b483ddb676c 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassProcessor.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.Ref;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
@@ -259,9 +260,13 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
new InlineToAnonymousConstructorProcessor(myClass, psiNewExpression, superType).run();
}
else {
- PsiJavaCodeReferenceElement element =
- JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory().createClassReferenceElement(superType.resolve());
- psiNewExpression.getClassReference().replace(element);
+ PsiClass target = superType.resolve();
+ assert target != null : superType;
+ PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
+ PsiJavaCodeReferenceElement element = factory.createClassReferenceElement(target);
+ PsiJavaCodeReferenceElement reference = psiNewExpression.getClassReference();
+ assert reference != null : psiNewExpression;
+ reference.replace(element);
}
}
catch (IncorrectOperationException e) {
@@ -276,7 +281,8 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
PsiType substType = classResolveResult.getSubstitutor().substitute(superType);
assert classResolveResult.getElement() == myClass;
try {
- typeElement.replace(factory.createTypeElement(substType));
+ PsiElement replaced = typeElement.replace(factory.createTypeElement(substType));
+ JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(replaced);
}
catch(IncorrectOperationException e) {
LOG.error(e);
diff --git a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/ReplaceWithSubtypeUsageInfo.java b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/ReplaceWithSubtypeUsageInfo.java
index f2a6a2e647a2..ec1e10df935b 100644
--- a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/ReplaceWithSubtypeUsageInfo.java
+++ b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/usageInfo/ReplaceWithSubtypeUsageInfo.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,21 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
- * User: anna
- * Date: 27-Aug-2008
- */
package com.intellij.refactoring.inlineSuperClass.usageInfo;
import com.intellij.openapi.diagnostic.Logger;
+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.util.TypeConversionUtil;
import com.intellij.refactoring.util.FixableUsageInfo;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
+/**
+ * @author anna
+ * @since 27-Aug-2008
+ */
public class ReplaceWithSubtypeUsageInfo extends FixableUsageInfo {
public static final Logger LOG = Logger.getInstance("#" + ReplaceWithSubtypeUsageInfo.class.getName());
private final PsiTypeElement myTypeElement;
@@ -51,8 +52,10 @@ public class ReplaceWithSubtypeUsageInfo extends FixableUsageInfo {
public void fixUsage() throws IncorrectOperationException {
if (myTypeElement.isValid()) {
- final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(myTypeElement.getProject()).getElementFactory();
- myTypeElement.replace(elementFactory.createTypeElement(myTargetClassType));
+ Project project = myTypeElement.getProject();
+ PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
+ PsiElement replaced = myTypeElement.replace(elementFactory.createTypeElement(myTargetClassType));
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced);
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java
index 6d333e9cb54b..3e92a19373ab 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java
@@ -23,6 +23,7 @@ package com.intellij.refactoring.move.moveClassesOrPackages;
import com.intellij.history.LocalHistory;
import com.intellij.history.LocalHistoryAction;
import com.intellij.ide.util.DirectoryChooser;
+import com.intellij.ide.util.PlatformPackageUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
@@ -266,7 +267,8 @@ public class MoveClassesOrPackagesImpl {
return aPackage != null ? getTargetPackageNameForMovedElement(aPackage) : "";
}
else if (psiElement != null) {
- PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(psiElement.getContainingFile().getContainingDirectory());
+ PsiDirectory directory = PlatformPackageUtil.getDirectory(psiElement);
+ PsiPackage aPackage = directory == null ? null : JavaDirectoryService.getInstance().getPackage(directory);
return aPackage != null ? aPackage.getQualifiedName() : "";
}
else {
diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.java
index f6cdabacedad..0004ff456cb6 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.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.refactoring.typeMigration;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.impl.PsiDiamondTypeUtil;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.CompositeElement;
@@ -109,18 +110,19 @@ public class TypeMigrationReplacementUtil {
if (!migratedType.isValid()) {
migratedType = JavaPsiFacade.getElementFactory(project).createTypeByFQClassName(migratedType.getCanonicalText());
}
- final PsiTypeElement typeElement =
- JavaPsiFacade.getInstance(project).getElementFactory().createTypeElement(migratedType);
+ final PsiTypeElement typeElement = JavaPsiFacade.getInstance(project).getElementFactory().createTypeElement(migratedType);
if (element instanceof PsiMethod) {
final PsiTypeElement returnTypeElement = ((PsiMethod)element).getReturnTypeElement();
if (returnTypeElement != null) {
- returnTypeElement.replace(typeElement);
+ final PsiElement replaced = returnTypeElement.replace(typeElement);
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced);
}
}
else if (element instanceof PsiVariable) {
final PsiTypeElement varTypeElement = ((PsiVariable)element).getTypeElement();
if (varTypeElement != null) {
- varTypeElement.replace(typeElement);
+ final PsiElement replaced = varTypeElement.replace(typeElement);
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced);
}
}
else {
diff --git a/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java b/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java
index 04c48bc71e40..966a7a3422ea 100644
--- a/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java
+++ b/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java
@@ -16,9 +16,8 @@
package com.intellij.spi;
import com.intellij.codeInsight.navigation.JavaGotoSuperHandler;
-import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiNameIdentifierOwner;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.spi.psi.SPIClassProviderReferenceElement;
@@ -27,11 +26,11 @@ import com.intellij.spi.psi.SPIClassProviderReferenceElement;
*/
public class SPIGotoSuperHandler extends JavaGotoSuperHandler {
@Override
- protected PsiNameIdentifierOwner getElement(PsiFile file, int offset) {
+ protected PsiElement getElement(PsiFile file, int offset) {
final SPIClassProviderReferenceElement
- providerElement = PsiTreeUtil.getParentOfType(file.findElementAt(offset), SPIClassProviderReferenceElement.class);
+ providerElement = PsiTreeUtil.getParentOfType(super.getElement(file, offset), SPIClassProviderReferenceElement.class);
if (providerElement != null) {
- return (PsiClass)providerElement.resolve();
+ return providerElement.resolve();
}
return null;
diff --git a/java/java-impl/src/com/intellij/util/xml/CanonicalPsiTypeConverterImpl.java b/java/java-impl/src/com/intellij/util/xml/CanonicalPsiTypeConverterImpl.java
index 877d27453b1b..254dc036547c 100644
--- a/java/java-impl/src/com/intellij/util/xml/CanonicalPsiTypeConverterImpl.java
+++ b/java/java-impl/src/com/intellij/util/xml/CanonicalPsiTypeConverterImpl.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.
@@ -80,7 +80,8 @@ public class CanonicalPsiTypeConverterImpl extends CanonicalPsiTypeConverter imp
final boolean isPrimitiveType = type instanceof PsiPrimitiveType;
return new JavaClassReferenceSet(trimmed, element, offset, false, CLASS_REFERENCE_PROVIDER) {
- protected JavaClassReference createReference(int refIndex, String subRefText, TextRange textRange, boolean staticImport) {
+ @NotNull
+ protected JavaClassReference createReference(int refIndex, @NotNull String subRefText, @NotNull TextRange textRange, boolean staticImport) {
return new JavaClassReference(this, textRange, refIndex, subRefText, staticImport) {
public boolean isSoft() {
return true;
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaSourceFilterScope.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaSourceFilterScope.java
index 59c7d6505859..b25f8c50911f 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaSourceFilterScope.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaSourceFilterScope.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 @@
package com.intellij.psi.impl.search;
import com.intellij.ide.highlighter.JavaClassFileType;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.JdkOrderEntry;
import com.intellij.openapi.roots.OrderEntry;
@@ -30,13 +31,25 @@ import com.intellij.psi.SdkResolveScopeProvider;
import com.intellij.psi.search.DelegatingGlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
public class JavaSourceFilterScope extends DelegatingGlobalSearchScope {
+ private static final Logger LOG = Logger.getInstance(JavaSourceFilterScope.class);
+
+ @Nullable
private final ProjectFileIndex myIndex;
public JavaSourceFilterScope(@NotNull final GlobalSearchScope delegate) {
super(delegate);
- myIndex = ProjectRootManager.getInstance(getProject()).getFileIndex();
+
+ Project project = getProject();
+ if (project != null) {
+ myIndex = ProjectRootManager.getInstance(project).getFileIndex();
+ }
+ else {
+ myIndex = null;
+ LOG.error("delegate.getProject() == null, delegate.getClass() == " + delegate.getClass());
+ }
}
@Override
@@ -45,6 +58,10 @@ public class JavaSourceFilterScope extends DelegatingGlobalSearchScope {
return false;
}
+ if (myIndex == null) {
+ return false;
+ }
+
if (JavaClassFileType.INSTANCE == file.getFileType()) {
return myIndex.isInLibraryClasses(file);
}
diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
index 8c36cfae1b88..577d38a30a15 100644
--- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
@@ -519,6 +519,14 @@ public class GenericsUtil {
else if (type instanceof PsiArrayType) {
return checkNotAssignable(bound, type, true);
}
+ else if (type instanceof PsiIntersectionType) {
+ for (PsiType psiType : ((PsiIntersectionType)type).getConjuncts()) {
+ if (!checkNotInBounds(psiType, bound, uncheckedConversionByDefault)) {
+ return false;
+ }
+ }
+ return true;
+ }
return false;
}
diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
index 15b3208b7426..54bd0241e64e 100644
--- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
@@ -60,6 +60,16 @@ public class LambdaUtil {
return getFunctionalInterfaceMethod(PsiUtil.resolveGenericsClassInType(functionalInterfaceType));
}
+ public static PsiMethod getFunctionalInterfaceMethod(@Nullable PsiElement element) {
+ if (element instanceof PsiLambdaExpression || element instanceof PsiMethodReferenceExpression) {
+ final PsiType samType = element instanceof PsiLambdaExpression
+ ? ((PsiLambdaExpression)element).getFunctionalInterfaceType()
+ : ((PsiMethodReferenceExpression)element).getFunctionalInterfaceType();
+ return getFunctionalInterfaceMethod(samType);
+ }
+ return null;
+ }
+
@Nullable
public static PsiMethod getFunctionalInterfaceMethod(PsiClassType.ClassResolveResult result) {
final PsiClass psiClass = result.getElement();
@@ -308,7 +318,7 @@ public class LambdaUtil {
final int finalLambdaIdx = adjustLambdaIdx(lambdaIdx, (PsiMethod)resolve, parameters);
if (finalLambdaIdx < parameters.length) {
if (!tryToSubstitute) return getNormalizedType(parameters[finalLambdaIdx]);
- return PsiResolveHelper.ourGuard.doPreventingRecursion(expression, true, new Computable<PsiType>() {
+ return PsiResolveHelper.ourGraphGuard.doPreventingRecursion(expression, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return resolveResult.getSubstitutor().substitute(getNormalizedType(parameters[finalLambdaIdx]));
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java b/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java
index bc61565bdc6c..47bd7be64c65 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiArrayType.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,7 +16,6 @@
package com.intellij.psi;
import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
/**
@@ -24,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
*
* @author max
*/
-public class PsiArrayType extends PsiType {
+public class PsiArrayType extends PsiType.Stub {
private final PsiType myComponentType;
/**
@@ -44,19 +43,33 @@ public class PsiArrayType extends PsiType {
@NotNull
@Override
public String getPresentableText() {
- return StringUtil.join(myComponentType.getPresentableText(), getAnnotationsTextPrefix(false, true, true), "[]");
+ return getText(myComponentType.getPresentableText(), "[]", false, true);
}
@NotNull
@Override
- public String getCanonicalText() {
- return StringUtil.join(myComponentType.getCanonicalText(), "[]");
+ public String getCanonicalText(boolean annotated) {
+ return getText(myComponentType.getCanonicalText(annotated), "[]", true, annotated);
}
@NotNull
@Override
public String getInternalCanonicalText() {
- return StringUtil.join(myComponentType.getInternalCanonicalText(), getAnnotationsTextPrefix(true, true, true), "[]");
+ return getText(myComponentType.getInternalCanonicalText(), "[]", true, true);
+ }
+
+ protected String getText(@NotNull String prefix, @NotNull String suffix, boolean qualified, boolean annotated) {
+ StringBuilder sb = new StringBuilder(prefix.length() + suffix.length());
+ sb.append(prefix);
+ if (annotated) {
+ PsiAnnotation[] annotations = getAnnotations();
+ if (annotations.length != 0) {
+ sb.append(' ');
+ PsiNameHelper.appendAnnotations(sb, annotations, qualified);
+ }
+ }
+ sb.append(suffix);
+ return sb.toString();
}
@Override
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
index 6de8d0202bef..8130b864ad9a 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author ven
*/
-public class PsiCapturedWildcardType extends PsiType {
+public class PsiCapturedWildcardType extends PsiType.Stub {
@NotNull private final PsiWildcardType myExistential;
@NotNull private final PsiElement myContext;
@Nullable private final PsiTypeParameter myParameter;
@@ -78,8 +78,8 @@ public class PsiCapturedWildcardType extends PsiType {
@NotNull
@Override
- public String getCanonicalText() {
- return myExistential.getCanonicalText();
+ public String getCanonicalText(boolean annotated) {
+ return myExistential.getCanonicalText(annotated);
}
@NotNull
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiClassType.java b/java/java-psi-api/src/com/intellij/psi/PsiClassType.java
index 30d9570048a7..722b9e2816a2 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiClassType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiClassType.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.
@@ -280,4 +280,23 @@ public abstract class PsiClassType extends PsiType {
}
};
}
+
+ /**
+ * Temporary class to facilitate transition to {@link #getCanonicalText(boolean)}.
+ */
+ public static abstract class Stub extends PsiClassType {
+ protected Stub(LanguageLevel languageLevel, @NotNull PsiAnnotation[] annotations) {
+ super(languageLevel, annotations);
+ }
+
+ @NotNull
+ @Override
+ public final String getCanonicalText() {
+ return getCanonicalText(false);
+ }
+
+ @NotNull
+ @Override
+ public abstract String getCanonicalText(boolean annotated);
+ }
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiDisjunctionType.java b/java/java-psi-api/src/com/intellij/psi/PsiDisjunctionType.java
index e9e0cf3116c4..1a4062e294fe 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiDisjunctionType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiDisjunctionType.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,7 +33,7 @@ import java.util.List;
* Composite type resulting from Project Coin's multi-catch statements, i.e. <code>FileNotFoundException | EOFException</code>.
* In most cases should be threatened via its least upper bound (<code>IOException</code> in the example above).
*/
-public class PsiDisjunctionType extends PsiType {
+public class PsiDisjunctionType extends PsiType.Stub {
private final PsiManager myManager;
private final List<PsiType> myTypes;
private final CachedValue<PsiType> myLubCache;
@@ -85,15 +85,21 @@ public class PsiDisjunctionType extends PsiType {
@Override
public String getPresentableText() {
return StringUtil.join(myTypes, new Function<PsiType, String>() {
- @Override public String fun(PsiType psiType) { return psiType.getPresentableText(); }
+ @Override
+ public String fun(PsiType psiType) {
+ return psiType.getPresentableText();
+ }
}, " | ");
}
@NotNull
@Override
- public String getCanonicalText() {
+ public String getCanonicalText(final boolean annotated) {
return StringUtil.join(myTypes, new Function<PsiType, String>() {
- @Override public String fun(PsiType psiType) { return psiType.getCanonicalText(); }
+ @Override
+ public String fun(PsiType psiType) {
+ return psiType.getCanonicalText(annotated);
+ }
}, " | ");
}
@@ -101,7 +107,10 @@ public class PsiDisjunctionType extends PsiType {
@Override
public String getInternalCanonicalText() {
return StringUtil.join(myTypes, new Function<PsiType, String>() {
- @Override public String fun(PsiType psiType) { return psiType.getInternalCanonicalText(); }
+ @Override
+ public String fun(PsiType psiType) {
+ return psiType.getInternalCanonicalText();
+ }
}, " | ");
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java b/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java
index 0d1447924d83..085854f51a65 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.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,7 +15,6 @@
*/
package com.intellij.psi;
-import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
/**
@@ -45,19 +44,19 @@ public class PsiEllipsisType extends PsiArrayType {
@NotNull
@Override
public String getPresentableText() {
- return StringUtil.join(getComponentType().getPresentableText(), getAnnotationsTextPrefix(false, true, true), "...");
+ return getText(getComponentType().getPresentableText(), "...", false, true);
}
@NotNull
@Override
- public String getCanonicalText() {
- return StringUtil.join(getComponentType().getCanonicalText(), "...");
+ public String getCanonicalText(boolean annotated) {
+ return getText(getComponentType().getCanonicalText(annotated), "...", true, annotated);
}
@NotNull
@Override
public String getInternalCanonicalText() {
- return StringUtil.join(getComponentType().getInternalCanonicalText(), getAnnotationsTextPrefix(true, true, true), "...");
+ return getText(getComponentType().getInternalCanonicalText(), "...", true, true);
}
@Override
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 215bb86b2b81..55a5e9d55260 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.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,7 +29,7 @@ import java.util.*;
*
* @author ven
*/
-public class PsiIntersectionType extends PsiType {
+public class PsiIntersectionType extends PsiType.Stub {
private final PsiType[] myConjuncts;
private PsiIntersectionType(@NotNull PsiType[] conjuncts) {
@@ -78,7 +78,8 @@ public class PsiIntersectionType extends PsiType {
for (PsiType existing : array) {
if (type != existing) {
final boolean allowUncheckedConversion = type instanceof PsiClassType && ((PsiClassType)type).isRaw();
- if (TypeConversionUtil.isAssignable(type, existing, allowUncheckedConversion)) {
+ if (TypeConversionUtil.isAssignable(GenericsUtil.eliminateWildcards(type),
+ GenericsUtil.eliminateWildcards(existing), allowUncheckedConversion)) {
iterator.remove();
break;
}
@@ -110,19 +111,19 @@ public class PsiIntersectionType extends PsiType {
@NotNull
@Override
- public String getCanonicalText() {
- return myConjuncts[0].getCanonicalText();
+ public String getCanonicalText(boolean annotated) {
+ return myConjuncts[0].getCanonicalText(annotated);
}
@NotNull
@Override
public String getInternalCanonicalText() {
- StringBuilder buffer = new StringBuilder();
- for (int i = 0; i < myConjuncts.length; i++) {
- buffer.append(myConjuncts[i].getInternalCanonicalText());
- if (i < myConjuncts.length - 1) buffer.append(" & ");
- }
- return buffer.toString();
+ return StringUtil.join(myConjuncts, new Function<PsiType, String>() {
+ @Override
+ public String fun(PsiType psiType) {
+ return psiType.getInternalCanonicalText();
+ }
+ }, " & ");
}
@Override
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java b/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java
index 6ae0fa6a081f..6e5e6563dc3b 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiNameHelper.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,8 +23,11 @@ import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Arrays;
+import java.util.List;
import java.util.regex.Pattern;
+import static com.intellij.util.ObjectUtils.assertNotNull;
import static com.intellij.util.ObjectUtils.notNull;
/**
@@ -37,7 +40,7 @@ public abstract class PsiNameHelper {
public static PsiNameHelper getInstance(Project project) {
return ServiceManager.getService(project, PsiNameHelper.class);
}
-
+
/**
* Checks if the specified text is a Java identifier, using the language level of the project
* with which the name helper is associated to filter out keywords.
@@ -121,30 +124,15 @@ public abstract class PsiNameHelper {
}
@NotNull
- public static String getPresentableText(@Nullable String refName, @NotNull PsiAnnotation[] annotations, @NotNull PsiType[] typeParameters) {
- if (typeParameters.length == 0 && annotations.length == 0) {
+ public static String getPresentableText(@Nullable String refName, @NotNull PsiAnnotation[] annotations, @NotNull PsiType[] types) {
+ if (types.length == 0 && annotations.length == 0) {
return refName != null ? refName : "";
}
StringBuilder buffer = new StringBuilder();
-
- if (annotations.length > 0) {
- for (PsiAnnotation annotation : annotations) {
- buffer.append(annotation.getText()).append(' ');
- }
- }
-
+ appendAnnotations(buffer, annotations, false);
buffer.append(refName);
-
- if (typeParameters.length > 0) {
- buffer.append("<");
- for (int i = 0; i < typeParameters.length; i++) {
- buffer.append(typeParameters[i].getPresentableText());
- if (i < typeParameters.length - 1) buffer.append(", ");
- }
- buffer.append(">");
- }
-
+ appendTypeArgs(buffer, types, false, true);
return buffer.toString();
}
@@ -262,4 +250,43 @@ public abstract class PsiNameHelper {
return subpackageName.equals(packageName) ||
subpackageName.startsWith(packageName) && subpackageName.charAt(packageName.length()) == '.';
}
+
+ public static void appendTypeArgs(@NotNull StringBuilder sb, @NotNull PsiType[] types, boolean canonical, boolean annotated) {
+ if (types.length == 0) return;
+
+ sb.append('<');
+ for (int i = 0; i < types.length; i++) {
+ if (i > 0) {
+ sb.append(canonical ? "," : ", ");
+ }
+
+ PsiType type = types[i];
+ if (canonical) {
+ sb.append(type.getCanonicalText(annotated));
+ }
+ else {
+ sb.append(type.getPresentableText());
+ }
+ }
+ sb.append('>');
+ }
+
+ public static boolean appendAnnotations(@NotNull StringBuilder sb, @NotNull PsiAnnotation[] annotations, boolean canonical) {
+ return appendAnnotations(sb, Arrays.asList(annotations), canonical);
+ }
+
+ public static boolean appendAnnotations(@NotNull StringBuilder sb, @NotNull List<PsiAnnotation> annotations, boolean canonical) {
+ for (PsiAnnotation annotation : annotations) {
+ sb.append('@');
+ if (canonical) {
+ sb.append(annotation.getQualifiedName());
+ sb.append(annotation.getParameterList().getText());
+ }
+ else {
+ sb.append(assertNotNull(annotation.getNameReferenceElement()).getText());
+ }
+ sb.append(' ');
+ }
+ return annotations.size() > 0;
+ }
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java b/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java
index dd6b0d4d6ef9..cad6cfda7234 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java
@@ -30,7 +30,7 @@ import java.util.Map;
/**
* Represents primitive types of Java language.
*/
-public class PsiPrimitiveType extends PsiType {
+public class PsiPrimitiveType extends PsiType.Stub {
private static final Map<String, PsiPrimitiveType> ourQNameToUnboxed = new THashMap<String, PsiPrimitiveType>();
private static final Map<PsiPrimitiveType, String> ourUnboxedToQName = new THashMap<PsiPrimitiveType, String>();
@@ -52,19 +52,29 @@ public class PsiPrimitiveType extends PsiType {
@NotNull
@Override
public String getPresentableText() {
- return getAnnotationsTextPrefix(false, false, true) + myName;
+ return getText(false, true);
}
@NotNull
@Override
- public String getCanonicalText() {
- return myName;
+ public String getCanonicalText(boolean annotated) {
+ return getText(true, annotated);
}
@NotNull
@Override
public String getInternalCanonicalText() {
- return getAnnotationsTextPrefix(true, false, true) + myName;
+ return getText(true, true);
+ }
+
+ private String getText(boolean qualified, boolean annotated) {
+ PsiAnnotation[] annotations = getAnnotations();
+ if (!annotated || annotations.length == 0) return myName;
+
+ StringBuilder sb = new StringBuilder();
+ PsiNameHelper.appendAnnotations(sb, annotations, qualified);
+ sb.append(myName);
+ return sb.toString();
}
/**
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiType.java b/java/java-psi-api/src/com/intellij/psi/PsiType.java
index cfbf026067bc..1dd67fb31a7f 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiType.java
@@ -84,6 +84,15 @@ public abstract class PsiType implements PsiAnnotationOwner {
*/
@NonNls
@NotNull
+ public String getCanonicalText(boolean annotated) {
+ return getCanonicalText();
+ }
+
+ /**
+ * Same as {@code getCanonicalText(false)}.
+ */
+ @NonNls
+ @NotNull
public abstract String getCanonicalText();
/**
@@ -284,24 +293,15 @@ public abstract class PsiType implements PsiAnnotationOwner {
return getAnnotations();
}
- @NotNull
+ /** @deprecated use {@link PsiNameHelper#appendAnnotations(StringBuilder, PsiAnnotation[], boolean)} (to remove in IDEA 14) */
+ @SuppressWarnings("UnusedDeclaration")
protected String getAnnotationsTextPrefix(boolean qualified, boolean leadingSpace, boolean trailingSpace) {
PsiAnnotation[] annotations = getAnnotations();
if (annotations.length == 0) return "";
StringBuilder sb = new StringBuilder();
if (leadingSpace) sb.append(' ');
- for (int i = 0; i < annotations.length; i++) {
- if (i > 0) sb.append(' ');
- PsiAnnotation annotation = annotations[i];
- if (qualified) {
- sb.append('@').append(annotation.getQualifiedName()).append(annotation.getParameterList().getText());
- }
- else {
- sb.append(annotation.getText());
- }
- }
- if (trailingSpace) sb.append(' ');
+ if (PsiNameHelper.appendAnnotations(sb, annotations, qualified) &&!trailingSpace) sb.setLength(sb.length() - 1);
return sb.toString();
}
@@ -310,4 +310,23 @@ public abstract class PsiType implements PsiAnnotationOwner {
//noinspection HardCodedStringLiteral
return "PsiType:" + getPresentableText();
}
+
+ /**
+ * Temporary class to facilitate transition to {@link #getCanonicalText(boolean)}.
+ */
+ protected static abstract class Stub extends PsiType {
+ protected Stub(@NotNull PsiAnnotation[] annotations) {
+ super(annotations);
+ }
+
+ @NotNull
+ @Override
+ public final String getCanonicalText() {
+ return getCanonicalText(false);
+ }
+
+ @NotNull
+ @Override
+ public abstract String getCanonicalText(boolean annotated);
+ }
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiWildcardType.java b/java/java-psi-api/src/com/intellij/psi/PsiWildcardType.java
index a3dd77aae361..d6518104b014 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiWildcardType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiWildcardType.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 org.jetbrains.annotations.Nullable;
*
* @author dsl
*/
-public class PsiWildcardType extends PsiType {
+public class PsiWildcardType extends PsiType.Stub {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiWildcardType");
private static final Key<PsiWildcardType> UNBOUNDED_WILDCARD = new Key<PsiWildcardType>("UNBOUNDED_WILDCARD");
@@ -83,21 +83,37 @@ public class PsiWildcardType extends PsiType {
@NotNull
@Override
public String getPresentableText() {
- return getAnnotationsTextPrefix(false, false, true) +
- (myBound == null ? "?" : (myIsExtending ? EXTENDS_PREFIX : SUPER_PREFIX) + myBound.getPresentableText());
+ return getText(false, true, myBound == null ? null : myBound.getPresentableText());
}
@Override
@NotNull
- public String getCanonicalText() {
- return myBound == null ? "?" : (myIsExtending ? EXTENDS_PREFIX : SUPER_PREFIX) + myBound.getCanonicalText();
+ public String getCanonicalText(boolean annotated) {
+ return getText(true, annotated, myBound == null ? null : myBound.getCanonicalText(annotated));
}
@NotNull
@Override
public String getInternalCanonicalText() {
- return getAnnotationsTextPrefix(true, false, true) +
- (myBound == null ? "?" : (myIsExtending ? EXTENDS_PREFIX : SUPER_PREFIX) + myBound.getInternalCanonicalText());
+ return getText(true, true, myBound == null ? null : myBound.getInternalCanonicalText());
+ }
+
+ private String getText(boolean qualified, boolean annotated, @Nullable String suffix) {
+ PsiAnnotation[] annotations = getAnnotations();
+ if ((!annotated || annotations.length == 0) && suffix == null) return "?";
+
+ StringBuilder sb = new StringBuilder();
+ if (annotated) {
+ PsiNameHelper.appendAnnotations(sb, annotations, qualified);
+ }
+ if (suffix == null) {
+ sb.append('?');
+ }
+ else {
+ sb.append(myIsExtending ? EXTENDS_PREFIX : SUPER_PREFIX);
+ sb.append(suffix);
+ }
+ return sb.toString();
}
@Override
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 0de45be17786..77fd0081d161 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
@@ -493,6 +493,13 @@ public class PsiImplUtil {
return PsiUtil.captureToplevelWildcards(type, expression);
}
+ final PsiElement parent = toplevel.getParent();
+ if (parent instanceof PsiExpressionList &&
+ PsiUtil.isLanguageLevel8OrHigher(parent) &&
+ parent.getParent() instanceof PsiCallExpression) {
+ return PsiUtil.captureToplevelWildcards(type, expression);
+ }
+
final PsiType normalized = doNormalizeWildcardByPosition(type, expression, toplevel);
LOG.assertTrue(normalized.isValid(), type);
if (normalized instanceof PsiClassType && !PsiUtil.isAccessedForWriting(toplevel)) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java
index 36a725aa3135..369ce919f5a1 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java
@@ -15,15 +15,18 @@
*/
package com.intellij.psi.impl.compiled;
+import com.intellij.diagnostic.PluginException;
import com.intellij.ide.caches.FileContent;
import com.intellij.ide.highlighter.JavaClassFileType;
import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.lang.ASTNode;
import com.intellij.lang.FileASTNode;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.progress.NonCancelableSection;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
@@ -35,6 +38,7 @@ import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
+import com.intellij.psi.compiled.ClassFileDecompilers;
import com.intellij.psi.impl.JavaPsiImplementationHelper;
import com.intellij.psi.impl.PsiFileEx;
import com.intellij.psi.impl.java.stubs.PsiClassStub;
@@ -324,7 +328,7 @@ public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub>
setMirror(mirrorTreeElement);
}
catch (InvalidMirrorException e) {
- LOG.error(file.getPath(), e);
+ LOG.error(file.getPath(), wrapException(e, file));
}
finally {
section.done();
@@ -337,6 +341,18 @@ public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub>
return mirrorTreeElement.getPsi();
}
+ private static Exception wrapException(InvalidMirrorException e, VirtualFile file) {
+ ClassFileDecompilers.Decompiler decompiler = ClassFileDecompilers.find(file);
+ if (decompiler instanceof ClassFileDecompilers.Light) {
+ PluginId pluginId = PluginManagerCore.getPluginByClassName(decompiler.getClass().getName());
+ if (pluginId != null) {
+ return new PluginException(e, pluginId);
+ }
+ }
+
+ return e;
+ }
+
@Override
public PsiFile getDecompiledPsiFile() {
return (PsiFile)getMirror();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java
index 599f756adbc1..16d971238684 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java
@@ -17,8 +17,7 @@ package com.intellij.psi.impl.compiled;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.openapi.util.NotNullLazyValue;
-import com.intellij.openapi.util.NullableLazyValue;
-import com.intellij.openapi.util.VolatileNullableLazyValue;
+import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.PsiJavaParserFacadeImpl;
@@ -28,7 +27,6 @@ import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.TreeElement;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement {
@NonNls static final char VARIANCE_NONE = '\0';
@@ -41,18 +39,18 @@ public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement
private final PsiElement myParent;
private final String myTypeText;
private final char myVariance;
- private final NullableLazyValue<ClsElementImpl> myChild;
+ private final NotNullLazyValue<Ref<ClsElementImpl>> myChild;
private final NotNullLazyValue<PsiType> myCachedType;
public ClsTypeElementImpl(@NotNull PsiElement parent, @NotNull String typeText, char variance) {
myParent = parent;
myTypeText = TypeInfo.internFrequentType(typeText);
myVariance = variance;
- myChild = new VolatileNullableLazyValue<ClsElementImpl>() {
- @Nullable
+ myChild = new AtomicNotNullLazyValue<Ref<ClsElementImpl>>() {
+ @NotNull
@Override
- protected ClsElementImpl compute() {
- return calculateChild();
+ protected Ref<ClsElementImpl> compute() {
+ return Ref.create(calculateChild());
}
};
myCachedType = new AtomicNotNullLazyValue<PsiType>() {
@@ -67,7 +65,7 @@ public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement
@Override
@NotNull
public PsiElement[] getChildren() {
- ClsElementImpl child = myChild.getValue();
+ ClsElementImpl child = myChild.getValue().get();
return child != null ? new PsiElement[]{child} : PsiElement.EMPTY_ARRAY;
}
@@ -111,7 +109,7 @@ public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement
public void setMirror(@NotNull TreeElement element) throws InvalidMirrorException {
setMirrorCheckingType(element, JavaElementType.TYPE);
- ClsElementImpl child = myChild.getValue();
+ ClsElementImpl child = myChild.getValue().get();
if (child != null) {
child.setMirror(element.getFirstChildNode());
}
@@ -157,7 +155,7 @@ public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement
PsiType result = PsiJavaParserFacadeImpl.getPrimitiveType(myTypeText);
if (result != null) return result;
- ClsElementImpl childElement = myChild.getValue();
+ ClsElementImpl childElement = myChild.getValue().get();
if (childElement instanceof ClsTypeElementImpl) {
if (isArray()) {
switch (myVariance) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java
index a43c02d8a7a4..f304fe250bae 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.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.
@@ -30,16 +30,16 @@ import java.util.List;
/**
* @author max
*/
-public class PsiClassReferenceType extends PsiClassType {
+public class PsiClassReferenceType extends PsiClassType.Stub {
@NotNull
private final PsiJavaCodeReferenceElement myReference;
- public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel langLevel) {
- this(reference, langLevel, collectAnnotations(reference));
+ public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel level) {
+ this(reference, level, collectAnnotations(reference));
}
- public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel langLevel, @NotNull PsiAnnotation[] annotations) {
- super(langLevel, annotations);
+ public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel level, @NotNull PsiAnnotation[] annotations) {
+ super(level, annotations);
myReference = reference;
}
@@ -89,7 +89,7 @@ public class PsiClassReferenceType extends PsiClassType {
return resolveGenerics().getElement();
}
- private static class DelegatingClassResolveResult implements ClassResolveResult {
+ private static class DelegatingClassResolveResult implements PsiClassType.ClassResolveResult {
private final JavaResolveResult myDelegate;
private DelegatingClassResolveResult(@NotNull JavaResolveResult delegate) {
@@ -182,19 +182,37 @@ public class PsiClassReferenceType extends PsiClassType {
@NotNull
@Override
public String getPresentableText() {
- return getAnnotationsTextPrefix(false, false, true) + PsiNameHelper.getPresentableText(myReference);
+ String presentableText = PsiNameHelper.getPresentableText(myReference);
+ PsiAnnotation[] annotations = getAnnotations();
+ if (annotations.length == 0) return presentableText;
+
+ StringBuilder sb = new StringBuilder();
+ PsiNameHelper.appendAnnotations(sb, annotations, false);
+ sb.append(presentableText);
+ return sb.toString();
}
@NotNull
@Override
- public String getCanonicalText() {
- return myReference.getCanonicalText();
+ public String getCanonicalText(boolean annotated) {
+ return getText(annotated);
}
@NotNull
@Override
public String getInternalCanonicalText() {
- return getAnnotationsTextPrefix(true, false, true) + getCanonicalText();
+ return getText(true);
+ }
+
+ private String getText(boolean annotated) {
+ if (myReference instanceof PsiJavaCodeReferenceElementImpl) {
+ PsiAnnotation[] annotations = getAnnotations();
+ if (!annotated || annotations.length == 0) annotations = null;
+ return ((PsiJavaCodeReferenceElementImpl)myReference).getCanonicalText(annotated, annotations);
+ }
+ else {
+ return myReference.getCanonicalText();
+ }
}
@NotNull
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java
index 9456c29f6ceb..77a45011144d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.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.psi.impl.source;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
@@ -30,11 +31,12 @@ import java.util.List;
/**
* @author dsl
*/
-public class PsiImmediateClassType extends PsiClassType {
+public class PsiImmediateClassType extends PsiClassType.Stub {
private final PsiClass myClass;
private final PsiSubstitutor mySubstitutor;
private final PsiManager myManager;
private String myCanonicalText;
+ private String myCanonicalTextAnnotated;
private String myPresentableText;
private String myInternalCanonicalText;
@@ -80,15 +82,15 @@ public class PsiImmediateClassType extends PsiClassType {
this(aClass, substitutor, null, PsiAnnotation.EMPTY_ARRAY);
}
- public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel languageLevel) {
- this(aClass, substitutor, languageLevel, PsiAnnotation.EMPTY_ARRAY);
+ public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel level) {
+ this(aClass, substitutor, level, PsiAnnotation.EMPTY_ARRAY);
}
public PsiImmediateClassType(@NotNull PsiClass aClass,
@NotNull PsiSubstitutor substitutor,
- @Nullable LanguageLevel languageLevel,
- @NotNull PsiAnnotation[] annotations) {
- super(languageLevel, annotations);
+ @Nullable LanguageLevel level,
+ @NotNull PsiAnnotation... annotations) {
+ super(level, annotations);
myClass = aClass;
myManager = aClass.getManager();
mySubstitutor = substitutor;
@@ -138,112 +140,119 @@ public class PsiImmediateClassType extends PsiClassType {
@Override
public String getPresentableText() {
if (myPresentableText == null) {
- StringBuilder buffer = new StringBuilder();
- buildText(myClass, mySubstitutor, buffer, false, false);
- myPresentableText = buffer.toString();
+ myPresentableText = getText(TextType.PRESENTABLE, true);
}
return myPresentableText;
}
@NotNull
@Override
- public String getCanonicalText() {
- if (myCanonicalText == null) {
- assert mySubstitutor.isValid();
- StringBuilder buffer = new StringBuilder();
- buildText(myClass, mySubstitutor, buffer, true, false);
- myCanonicalText = buffer.toString();
+ public String getCanonicalText(boolean annotated) {
+ String cached = annotated ? myCanonicalTextAnnotated : myCanonicalText;
+ if (cached == null) {
+ cached = getText(TextType.CANONICAL, annotated);
+ if (annotated) myCanonicalTextAnnotated = cached;
+ else myCanonicalText = cached;
}
- return myCanonicalText;
+ return cached;
}
@NotNull
@Override
public String getInternalCanonicalText() {
if (myInternalCanonicalText == null) {
- StringBuilder buffer = new StringBuilder();
- buildText(myClass, mySubstitutor, buffer, true, true);
- myInternalCanonicalText = buffer.toString();
+ myInternalCanonicalText = getText(TextType.INT_CANONICAL, true);
}
return myInternalCanonicalText;
}
+ private enum TextType { PRESENTABLE, CANONICAL, INT_CANONICAL }
+
+ private String getText(@NotNull TextType textType, boolean annotated) {
+ assert mySubstitutor.isValid();
+ StringBuilder buffer = new StringBuilder();
+ buildText(myClass, mySubstitutor, buffer, textType, annotated);
+ return buffer.toString();
+ }
+
private void buildText(@NotNull PsiClass aClass,
@NotNull PsiSubstitutor substitutor,
@NotNull StringBuilder buffer,
- boolean canonical,
- boolean internal) {
+ @NotNull TextType textType,
+ boolean annotated) {
if (aClass instanceof PsiAnonymousClass) {
- ClassResolveResult baseResolveResult = ((PsiAnonymousClass) aClass).getBaseClassType().resolveGenerics();
+ ClassResolveResult baseResolveResult = ((PsiAnonymousClass)aClass).getBaseClassType().resolveGenerics();
PsiClass baseClass = baseResolveResult.getElement();
- PsiSubstitutor baseSub = baseResolveResult.getSubstitutor();
if (baseClass != null) {
- buildText(baseClass, baseSub, buffer, canonical, internal);
+ buildText(baseClass, baseResolveResult.getSubstitutor(), buffer, textType, false);
}
return;
}
- if (canonical == internal) {
- buffer.append(getAnnotationsTextPrefix(internal, false, true));
- }
+ boolean qualified = textType != TextType.PRESENTABLE;
PsiClass enclosingClass = null;
if (!aClass.hasModifierProperty(PsiModifier.STATIC)) {
- final PsiElement parent = aClass.getParent();
+ PsiElement parent = aClass.getParent();
if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass)) {
enclosingClass = (PsiClass)parent;
}
}
if (enclosingClass != null) {
- buildText(enclosingClass, substitutor, buffer, canonical, false);
+ buildText(enclosingClass, substitutor, buffer, textType, false);
buffer.append('.');
- buffer.append(aClass.getName());
}
- else {
- final String name;
- if (!canonical) {
- name = aClass.getName();
- }
- else {
- final String qualifiedName = aClass.getQualifiedName();
- if (qualifiedName == null) {
- name = aClass.getName();
- }
- else {
- name = qualifiedName;
+ else if (qualified) {
+ String fqn = aClass.getQualifiedName();
+ if (fqn != null) {
+ String prefix = StringUtil.getPackageName(fqn);
+ if (!StringUtil.isEmpty(prefix)) {
+ buffer.append(prefix);
+ buffer.append('.');
}
}
- buffer.append(name);
}
+ if (annotated) {
+ PsiNameHelper.appendAnnotations(buffer, getAnnotations(), qualified);
+ }
+
+ buffer.append(aClass.getName());
+
PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
if (typeParameters.length > 0) {
- StringBuilder pineBuffer = new StringBuilder();
- pineBuffer.append('<');
+ int pos = buffer.length();
+ buffer.append('<');
+
for (int i = 0; i < typeParameters.length; i++) {
PsiTypeParameter typeParameter = typeParameters[i];
PsiUtilCore.ensureValid(typeParameter);
- if (i > 0) pineBuffer.append(',');
- final PsiType substitutionResult = substitutor.substitute(typeParameter);
+
+ if (i > 0) {
+ buffer.append(',');
+ if (textType == TextType.PRESENTABLE) buffer.append(' ');
+ }
+
+ PsiType substitutionResult = substitutor.substitute(typeParameter);
if (substitutionResult == null) {
- pineBuffer = null;
+ buffer.setLength(pos);
+ pos = -1;
break;
}
PsiUtil.ensureValidType(substitutionResult);
- if (canonical) {
- if (internal) {
- pineBuffer.append(substitutionResult.getInternalCanonicalText());
- }
- else {
- pineBuffer.append(substitutionResult.getCanonicalText());
- }
+
+ if (textType == TextType.PRESENTABLE) {
+ buffer.append(substitutionResult.getPresentableText());
+ }
+ else if (textType == TextType.CANONICAL) {
+ buffer.append(substitutionResult.getCanonicalText(annotated));
}
else {
- pineBuffer.append(substitutionResult.getPresentableText());
+ buffer.append(substitutionResult.getInternalCanonicalText());
}
}
- if (pineBuffer != null) {
- buffer.append(pineBuffer);
+
+ if (pos >= 0) {
buffer.append('>');
}
}
@@ -265,7 +274,6 @@ public class PsiImmediateClassType extends PsiClassType {
return false;
}
return equals(patternType);
-
}
@Override
@@ -277,14 +285,12 @@ public class PsiImmediateClassType extends PsiClassType {
@Override
@NotNull
public LanguageLevel getLanguageLevel() {
- if (myLanguageLevel != null) return myLanguageLevel;
- return PsiUtil.getLanguageLevel(myClass);
+ return myLanguageLevel != null ? myLanguageLevel : PsiUtil.getLanguageLevel(myClass);
}
@NotNull
@Override
- public PsiClassType setLanguageLevel(@NotNull final LanguageLevel languageLevel) {
- if (languageLevel.equals(myLanguageLevel)) return this;
- return new PsiImmediateClassType(myClass, mySubstitutor, languageLevel,getAnnotations());
+ public PsiClassType setLanguageLevel(@NotNull LanguageLevel level) {
+ return level.equals(myLanguageLevel) ? this : new PsiImmediateClassType(myClass, mySubstitutor, level, getAnnotations());
}
}
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 396b750c8c2a..5ee1243b09ce 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
@@ -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.
@@ -49,6 +49,7 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Arrays;
import java.util.List;
public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement implements PsiJavaCodeReferenceElement, SourceJavaCodeReference {
@@ -255,36 +256,47 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
@Override
@NotNull
public String getCanonicalText() {
+ return getCanonicalText(false, null);
+ }
+
+ @NotNull
+ public String getCanonicalText(boolean annotated, @Nullable PsiAnnotation[] annotations) {
switch (getKind()) {
case CLASS_NAME_KIND:
case CLASS_OR_PACKAGE_NAME_KIND:
case CLASS_IN_QUALIFIED_NEW_KIND:
final PsiElement target = resolve();
if (target instanceof PsiClass) {
- final PsiClass aClass = (PsiClass)target;
- String name = aClass.getQualifiedName();
- if (name == null) {
- name = aClass.getName(); //?
+ PsiClass aClass = (PsiClass)target;
+ StringBuilder buffer = new StringBuilder();
+
+ PsiElement qualifier = getQualifier();
+ String prefix = null;
+ if (qualifier instanceof PsiJavaCodeReferenceElementImpl) {
+ prefix = ((PsiJavaCodeReferenceElementImpl)qualifier).getCanonicalText(annotated, null);
}
- final PsiType[] types = getTypeParameters();
- if (types.length == 0) {
- final PsiElement qualifier = getQualifier();
- if (qualifier instanceof PsiJavaCodeReferenceElement) {
- return StringUtil.getQualifiedName(((PsiJavaCodeReferenceElement)qualifier).getCanonicalText(), aClass.getName());
+ else {
+ String fqn = aClass.getQualifiedName();
+ if (fqn != null) {
+ prefix = StringUtil.getPackageName(fqn);
}
- return name;
}
- final StringBuilder buf = new StringBuilder();
- buf.append(name);
- buf.append('<');
- for (int i = 0; i < types.length; i++) {
- if (i > 0) buf.append(',');
- buf.append(types[i].getCanonicalText());
+ if (!StringUtil.isEmpty(prefix)) {
+ buffer.append(prefix);
+ buffer.append('.');
}
- buf.append('>');
- return buf.toString();
+ if (annotated) {
+ List<PsiAnnotation> list = annotations != null ? Arrays.asList(annotations) : getAnnotations();
+ PsiNameHelper.appendAnnotations(buffer, list, true);
+ }
+
+ buffer.append(aClass.getName());
+
+ PsiNameHelper.appendTypeArgs(buffer, getTypeParameters(), true, annotated);
+
+ return buffer.toString();
}
else if (target instanceof PsiPackage) {
return ((PsiPackage)target).getQualifiedName();
@@ -293,6 +305,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
LOG.assertTrue(target == null, target);
return getNormalizedText();
}
+
case PACKAGE_NAME_KIND:
case CLASS_FQ_NAME_KIND:
case CLASS_FQ_OR_PACKAGE_NAME_KIND:
@@ -327,7 +340,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
if (incompleteCode && result.length == 0 && kind != CLASS_FQ_NAME_KIND && kind != CLASS_FQ_OR_PACKAGE_NAME_KIND) {
VariableResolverProcessor processor = new VariableResolverProcessor(referenceElement, containingFile);
- PsiScopesUtil.resolveAndWalk(processor, referenceElement, null, incompleteCode);
+ PsiScopesUtil.resolveAndWalk(processor, referenceElement, null, true);
result = processor.getResult();
if (result.length == 0 && kind == CLASS_NAME_KIND) {
result = referenceElement.resolve(PACKAGE_NAME_KIND, containingFile);
@@ -457,16 +470,16 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
case CLASS_FQ_OR_PACKAGE_NAME_KIND:
case CLASS_OR_PACKAGE_NAME_KIND: {
int classKind = kind == CLASS_OR_PACKAGE_NAME_KIND ? CLASS_NAME_KIND : CLASS_FQ_NAME_KIND;
- JavaResolveResult[] result = resolve(classKind,containingFile);
+ JavaResolveResult[] result = resolve(classKind, containingFile);
if (result.length == 1 && !result[0].isAccessible()) {
- JavaResolveResult[] packageResult = resolve(PACKAGE_NAME_KIND,containingFile);
+ JavaResolveResult[] packageResult = resolve(PACKAGE_NAME_KIND, containingFile);
if (packageResult.length != 0) {
result = packageResult;
}
}
else if (result.length == 0) {
- result = resolve(PACKAGE_NAME_KIND,containingFile);
+ result = resolve(PACKAGE_NAME_KIND, containingFile);
}
return result;
@@ -607,7 +620,12 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
for (PsiAnnotation annotation : annotations) {
if (annotation.getParent() != newParent) {
- newParent.addAfter(annotation, anchor);
+ if (anchor != null) {
+ newParent.addAfter(annotation, anchor);
+ }
+ else {
+ newParent.add(annotation);
+ }
annotation.delete();
}
}
@@ -935,7 +953,6 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
final PsiReferenceParameterList parameterList = getParameterList();
if (parameterList == null) return PsiType.EMPTY_ARRAY;
return parameterList.getTypeArguments();
-
}
@Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java
index 5b76439ef406..20db589bef5c 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java
@@ -225,15 +225,21 @@ public class JavaResolveUtil {
return true;
}
- public static void substituteResults(@NotNull PsiJavaCodeReferenceElement ref, @NotNull JavaResolveResult[] result) {
+ public static void substituteResults(final @NotNull PsiJavaCodeReferenceElement ref, @NotNull JavaResolveResult[] result) {
if (result.length > 0 && result[0].getElement() instanceof PsiClass) {
- PsiType[] parameters = ref.getTypeParameters();
for (int i = 0; i < result.length; i++) {
- CandidateInfo resolveResult = (CandidateInfo)result[i];
- PsiElement resultElement = resolveResult.getElement();
+ final CandidateInfo resolveResult = (CandidateInfo)result[i];
+ final PsiElement resultElement = resolveResult.getElement();
if (resultElement instanceof PsiClass && ((PsiClass)resultElement).hasTypeParameters()) {
- PsiSubstitutor substitutor = resolveResult.getSubstitutor().putAll((PsiClass)resultElement, parameters);
- result[i] = new CandidateInfo(resolveResult, substitutor);
+ PsiSubstitutor substitutor = resolveResult.getSubstitutor();
+ result[i] = new CandidateInfo(resolveResult, substitutor) {
+ @NotNull
+ @Override
+ public PsiSubstitutor getSubstitutor() {
+ final PsiType[] parameters = ref.getTypeParameters();
+ return super.getSubstitutor().putAll((PsiClass)resultElement, parameters);
+ }
+ };
}
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java
index a52ea73a18d5..b4b188c772cc 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/FunctionalInterfaceParameterizationUtil.java
@@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.resolve.graphInference;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeEqualityConstraint;
-import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
@@ -102,7 +101,7 @@ public class FunctionalInterfaceParameterizationUtil {
return null;
}
- final PsiSubstitutor substitutor = session.resolveDependencies(session.getInferenceVariables());
+ final PsiSubstitutor substitutor = session.retrieveNonPrimitiveEqualsBounds(session.getInferenceVariables());
final PsiType[] newTypeParameters = new PsiType[parameters.length];
for (int i = 0; i < typeParameters.length; i++) {
PsiTypeParameter typeParameter = typeParameters[i];
@@ -119,14 +118,10 @@ public class FunctionalInterfaceParameterizationUtil {
return null;
}
- if (!TypeConversionUtil.containsWildcards(parameterization)) {
+ if (!TypeConversionUtil.containsWildcards(parameterization) && psiClassType.isAssignableFrom(parameterization)) {
return parameterization;
}
- if (!psiClassType.isAssignableFrom(parameterization)) {
- return null;
- }
-
return getNonWildcardParameterization((PsiClassType)psiClassType);
}
return null;
@@ -169,27 +164,32 @@ public class FunctionalInterfaceParameterizationUtil {
for (int i = 0; i < parameters.length; i++) {
PsiType paramType = parameters[i];
if (paramType instanceof PsiWildcardType) {
- final PsiClassType[] extendsListTypes = typeParameters[i].getExtendsListTypes();
- final PsiClassType Bi = extendsListTypes.length > 0 ? extendsListTypes[0]
- : PsiType.getJavaLangObject(psiClass.getManager(),
- GlobalSearchScope.allScope(psiClass.getProject()));
- if (PsiPolyExpressionUtil.mentionsTypeParameters(Bi, typeParametersSet)) {
- return null;
+ final PsiType bound = GenericsUtil.eliminateWildcards(((PsiWildcardType)paramType).getBound(), false);
+ if (((PsiWildcardType)paramType).isSuper()) {
+ newParameters[i] = bound;
}
-
- final PsiType bound = ((PsiWildcardType)paramType).getBound();
- if (bound == null) {
- newParameters[i] = Bi;
- } else if (((PsiWildcardType)paramType).isExtends()){
- newParameters[i] = GenericsUtil.getGreatestLowerBound(Bi, GenericsUtil.eliminateWildcards(bound, false));
- } else {
- newParameters[i] = GenericsUtil.eliminateWildcards(bound, false);
+ else {
+ newParameters[i] = bound != null ? bound : PsiType.getJavaLangObject(psiClass.getManager(), psiClassType.getResolveScope());
+ for (PsiClassType paramBound : typeParameters[i].getExtendsListTypes()) {
+ if (!PsiPolyExpressionUtil.mentionsTypeParameters(paramBound, typeParametersSet)) {
+ newParameters[i] = GenericsUtil.getGreatestLowerBound(paramBound, newParameters[i]);
+ }
+ }
}
} else {
newParameters[i] = paramType;
}
}
- return JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, newParameters);
+
+ if (!isWellFormed(psiClass, typeParameters, newParameters)) {
+ return null;
+ }
+
+ final PsiClassType parameterization = JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, newParameters);
+ if (!psiClassType.isAssignableFrom(parameterization)) {
+ return null;
+ }
+ return parameterization;
}
return null;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
index cc666815c2d2..f30c7ae6382c 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
@@ -110,18 +110,6 @@ public class InferenceIncorporationPhase {
}
}
}
-
- //todo no such a rule in spec?!
- for (PsiType lowerBound : lowerBounds) {
- if (mySession.isProperType(lowerBound)) {
- final PsiSubstitutor substitutor = PsiSubstitutor.EMPTY.put(inferenceVariable.getParameter(), lowerBound);
- for (PsiType upperBound : upperBounds) {
- if (!mySession.isProperType(upperBound)) {
- addConstraint(new StrictSubtypingConstraint(substitutor.substitute(upperBound), lowerBound));
- }
- }
- }
- }
}
for (Pair<PsiTypeParameter[], PsiClassType> capture : myCaptures) {
@@ -389,21 +377,4 @@ public class InferenceIncorporationPhase {
}
}
}
-
- public PsiSubstitutor checkIncorporated(PsiSubstitutor substitutor, Collection<InferenceVariable> variables) {
- for (InferenceVariable variable : variables) { //todo equals bounds?
- for (PsiType lowerBound : variable.getBounds(InferenceBound.LOWER)) {
- lowerBound = substitutor.substitute(lowerBound);
- if (mySession.isProperType(lowerBound)) {
- for (PsiType upperBound : variable.getBounds(InferenceBound.UPPER)) {
- upperBound = substitutor.substitute(upperBound);
- if (mySession.isProperType(upperBound) && !TypeConversionUtil.isAssignable(upperBound, lowerBound)) {
- return null;
- }
- }
- }
- }
- }
- return substitutor;
- }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
index abde4616fe77..53911011bc17 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
@@ -20,15 +20,8 @@ import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
-import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.*;
import com.intellij.psi.infos.MethodCandidateInfo;
-import com.intellij.psi.scope.MethodProcessorSetupFailedException;
-import com.intellij.psi.scope.PsiConflictResolver;
-import com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver;
-import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
-import com.intellij.psi.scope.processor.MethodResolverProcessor;
-import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiTypesUtil;
@@ -174,7 +167,8 @@ public class InferenceSession {
return true;
}
- private static PsiType getParameterType(PsiParameter[] parameters, PsiExpression[] args, int i, PsiSubstitutor substitutor) {
+ private static PsiType getParameterType(PsiParameter[] parameters, PsiExpression[] args, int i, @Nullable PsiSubstitutor substitutor) {
+ if (substitutor == null) return null;
PsiType parameterType = substitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType());
if (parameterType instanceof PsiEllipsisType) {
final PsiExpression arg = args[i];
@@ -213,7 +207,7 @@ public class InferenceSession {
PsiMethod parentMethod) {
if (!repeatInferencePhases(true)) {
//inferred result would be checked as candidate won't be applicable
- return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor, false);
+ return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor);
}
if (parentMethod != null) {
@@ -299,17 +293,17 @@ public class InferenceSession {
}
}
} else {
- return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor, false);
+ return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor);
}
return prepareSubstitution();
}
- public PsiSubstitutor resolveDependencies(Collection<InferenceVariable> variables) {
+ public PsiSubstitutor retrieveNonPrimitiveEqualsBounds(Collection<InferenceVariable> variables) {
PsiSubstitutor substitutor = mySiteSubstitutor;
for (InferenceVariable variable : variables) {
final PsiType equalsBound = getEqualsBound(variable, substitutor);
- if (equalsBound != PsiType.NULL) {
+ if (!(equalsBound instanceof PsiPrimitiveType)) {
substitutor = substitutor.put(variable.getParameter(), equalsBound);
}
}
@@ -340,9 +334,13 @@ public class InferenceSession {
return false;
}
- public void initBounds(PsiTypeParameter... typeParameters) {
+ public boolean initBounds(PsiTypeParameter... typeParameters) {
+ boolean sameMethodCall = false;
for (PsiTypeParameter parameter : typeParameters) {
- if (myInferenceVariables.containsKey(parameter)) continue;
+ if (myInferenceVariables.containsKey(parameter)) {
+ sameMethodCall = true;
+ continue;
+ }
InferenceVariable variable = new InferenceVariable(parameter);
boolean added = false;
final PsiClassType[] extendsListTypes = parameter.getExtendsListTypes();
@@ -359,29 +357,19 @@ public class InferenceSession {
}
myInferenceVariables.put(parameter, variable);
}
- }
-
- public void addCapturedVariable(PsiTypeParameter param) {
- initBounds(param);
+ return sameMethodCall;
}
private void initReturnTypeConstraint(PsiMethod method, final PsiCallExpression context) {
- if (PsiPolyExpressionUtil.isMethodCallPolyExpression(context, method) ||
- context instanceof PsiNewExpression && PsiDiamondType.ourDiamondGuard.currentStack().contains(context)) {
+ if (PsiPolyExpressionUtil.isMethodCallPolyExpression(context, method)) {
PsiType returnType = method.getReturnType();
if (!PsiType.VOID.equals(returnType) && returnType != null) {
- returnType = PsiImplUtil.normalizeWildcardTypeByPosition(returnType, context);
PsiType targetType = PsiTypesUtil.getExpectedTypeByParent(context);
if (targetType == null) {
- targetType = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(context, false, new Computable<PsiType>() {
- @Override
- public PsiType compute() {
- return getTargetType(context);
- }
- });
+ targetType = getTargetType(context);
}
if (targetType != null) {
- registerConstraints(returnType, targetType);
+ registerConstraints(PsiUtil.isRawSubstitutor(method, mySiteSubstitutor) ? returnType : mySiteSubstitutor.substitute(returnType), targetType);
}
}
}
@@ -397,7 +385,7 @@ public class InferenceSession {
public void registerConstraints(PsiType returnType, PsiType targetType) {
final InferenceVariable inferenceVariable = shouldResolveAndInstantiate(returnType, targetType);
if (inferenceVariable != null) {
- final PsiSubstitutor substitutor = resolveSubset(Collections.singletonList(inferenceVariable), mySiteSubstitutor, true);
+ final PsiSubstitutor substitutor = resolveSubset(Collections.singletonList(inferenceVariable), mySiteSubstitutor);
myConstraints.add(new TypeCompatibilityConstraint(targetType, PsiUtil.captureToplevelWildcards(substitutor.substitute(inferenceVariable.getParameter()), myContext)));
}
else {
@@ -412,7 +400,7 @@ public class InferenceSession {
PsiTypeParameter[] copy = new PsiTypeParameter[typeParameters.length];
for (int i = 0; i < typeParameters.length; i++) {
PsiTypeParameter typeParameter = typeParameters[i];
- copy[i] = elementFactory.createTypeParameterFromText(typeParameter.getName(), null);
+ copy[i] = elementFactory.createTypeParameterFromText("rCopy" + typeParameter.getName(), null);
initBounds(copy[i]);
subst = subst.put(typeParameter, elementFactory.createType(copy[i]));
}
@@ -495,7 +483,7 @@ public class InferenceSession {
return false;
}
- private PsiType getTargetType(final PsiExpression context) {
+ private static PsiType getTargetType(final PsiExpression context) {
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(context.getParent());
if (parent instanceof PsiExpressionList) {
PsiElement gParent = parent.getParent();
@@ -505,28 +493,8 @@ public class InferenceSession {
if (gParent instanceof PsiCallExpression) {
final PsiExpressionList argumentList = ((PsiCallExpression)gParent).getArgumentList();
if (argumentList != null) {
- final Pair<PsiMethod, PsiSubstitutor> pair = MethodCandidateInfo.getCurrentMethod(argumentList);
- final PsiFile placeFile = context.getContainingFile();
- final JavaMethodsConflictResolver conflictResolver = new JavaMethodsConflictResolver(argumentList, PsiUtil.getLanguageLevel(placeFile)){
- @Override
- protected PsiType[] getArgumentTypes() {
- return InferenceSession.getArgumentTypes(argumentList, context);
- }
- };
- final MethodCandidatesProcessor processor = new MethodResolverProcessor((PsiCallExpression)gParent, placeFile, new PsiConflictResolver[]{conflictResolver}) {
- @Override
- protected PsiType[] getExpressionTypes(PsiExpressionList argumentList) {
- return getArgumentTypes(argumentList, context);
- }
- };
- try {
- PsiScopesUtil.setupAndRunProcessor(processor, (PsiCallExpression)gParent, false);
- }
- catch (MethodProcessorSetupFailedException e) {
- return null;
- }
- final JavaResolveResult[] results = processor.getResult();
- return results.length == 1 ? getTypeByMethod(context, argumentList, pair, results[0], results[0].getElement()) : null;
+ final JavaResolveResult result = ((PsiCallExpression)gParent).resolveMethodGenerics();
+ return getTypeByMethod(context, argumentList, result, result.getElement());
}
}
} else if (parent instanceof PsiConditionalExpression) {
@@ -546,30 +514,9 @@ public class InferenceSession {
return null;
}
- private static PsiType[] getArgumentTypes(PsiExpressionList argumentList, PsiExpression context) {
- if (argumentList != null) {
- final PsiExpression[] expressions = argumentList.getExpressions();
- final int idx = LambdaUtil.getLambdaIdx(argumentList, context);
- final PsiType[] types = PsiType.createArray(expressions.length);
- for (int i = 0; i < expressions.length; i++) {
- if (i != idx) {
- types[i] = expressions[i].getType();
- }
- else {
- types[i] = PsiType.NULL;
- }
- }
- return types;
- }
- else {
- return null;
- }
- }
-
- private PsiType getTypeByMethod(PsiExpression context,
- PsiExpressionList argumentList,
- Pair<PsiMethod, PsiSubstitutor> pair,
- JavaResolveResult result, PsiElement parentMethod) {
+ private static PsiType getTypeByMethod(PsiExpression context,
+ PsiExpressionList argumentList,
+ final JavaResolveResult result, PsiElement parentMethod) {
if (parentMethod instanceof PsiMethod) {
final PsiParameter[] parameters = ((PsiMethod)parentMethod).getParameterList().getParameters();
if (parameters.length == 0) return null;
@@ -581,23 +528,13 @@ public class InferenceSession {
}
final int i = ArrayUtilRt.find(args, arg);
if (i < 0) return null;
- final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(argumentList, PsiCallExpression.class);
- if (callExpression != null && callExpression.getTypeArguments().length > 0) {
- return getParameterType(parameters, args, i, ((MethodCandidateInfo)result).typeArgumentsSubstitutor());
- }
- final PsiType parameterType = getParameterType(parameters, args, i, pair != null ? pair.second : PsiSubstitutor.EMPTY);
- args[i] = null;
- final PsiTypeParameter[] typeParameters = ((PsiMethod)parentMethod).getTypeParameters();
- final InferenceSession session = new InferenceSession(typeParameters, ((MethodCandidateInfo)result).getSiteSubstitutor(), myManager, argumentList);
- session.initExpressionConstraints(parameters, args, argumentList, (PsiMethod)parentMethod);
- if (session.tryToInfer(parameters, args, callExpression, (PsiMethod)parentMethod) != null) {
- return null;
- }
- final Collection<PsiTypeParameter> params = session.getTypeParams();
- initBounds(params.toArray(new PsiTypeParameter[params.size()]));
- liftBounds(session.getInferenceVariables());
- final PsiSubstitutor substitutor = ((MethodCandidateInfo)result).getSiteSubstitutor();
- return substitutor.substitute(parameterType);
+ return getParameterType(parameters, args, i, PsiResolveHelper.ourGraphGuard.doPreventingRecursion(argumentList.getParent(), false,
+ new Computable<PsiSubstitutor>() {
+ @Override
+ public PsiSubstitutor compute() {
+ return result.getSubstitutor();
+ }
+ }));
}
return null;
}
@@ -720,7 +657,7 @@ public class InferenceSession {
while (!allVars.isEmpty()) {
final List<InferenceVariable> vars = InferenceVariablesOrder.resolveOrder(allVars, this);
if (!myIncorporationPhase.hasCaptureConstraints(vars)) {
- final PsiSubstitutor firstSubstitutor = resolveSubset(vars, substitutor, true);
+ final PsiSubstitutor firstSubstitutor = resolveSubset(vars, substitutor);
if (firstSubstitutor != null) {
substitutor = firstSubstitutor;
allVars.removeAll(vars);
@@ -731,7 +668,7 @@ public class InferenceSession {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(getManager().getProject());
for (InferenceVariable var : vars) {
final PsiTypeParameter parameter = var.getParameter();
- final PsiTypeParameter copy = elementFactory.createTypeParameterFromText(parameter.getName(), null);
+ final PsiTypeParameter copy = elementFactory.createTypeParameterFromText("z" + parameter.getName(), null);
final PsiType lub = getLowerBound(var, substitutor);
final PsiType glb = getUpperBound(var, substitutor);
final InferenceVariable zVariable = new InferenceVariable(copy);
@@ -744,6 +681,8 @@ public class InferenceSession {
zVariable.addBound(lub, InferenceBound.LOWER);
}
myInferenceVariables.put(copy, zVariable);
+ allVars.add(zVariable);
+ var.addBound(elementFactory.createType(copy), InferenceBound.EQ);
}
myIncorporationPhase.forgetCaptures(vars);
if (!myIncorporationPhase.incorporate()) {
@@ -762,7 +701,7 @@ public class InferenceSession {
}, substitutor);
}
- private PsiSubstitutor resolveSubset(Collection<InferenceVariable> vars, PsiSubstitutor substitutor, boolean checkResult) {
+ private PsiSubstitutor resolveSubset(Collection<InferenceVariable> vars, PsiSubstitutor substitutor) {
for (InferenceVariable var : vars) {
LOG.assertTrue(var.getInstantiation() == PsiType.NULL);
final PsiTypeParameter typeParameter = var.getParameter();
@@ -781,7 +720,7 @@ public class InferenceSession {
}
}
- return checkResult ? myIncorporationPhase.checkIncorporated(substitutor, vars) : substitutor;
+ return substitutor;
}
private PsiType getUpperBound(InferenceVariable var, PsiSubstitutor substitutor) {
@@ -872,7 +811,7 @@ public class InferenceSession {
}
//resolve input variables
- PsiSubstitutor substitutor = resolveSubset(varsToResolve, mySiteSubstitutor, true);
+ PsiSubstitutor substitutor = resolveSubset(varsToResolve, mySiteSubstitutor);
if (substitutor == null) {
return false;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java
index a67b64eea669..a629175b9d48 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java
@@ -48,17 +48,6 @@ public class CheckedExceptionCompatibilityConstraint extends InputOutputConstrai
if (!PsiPolyExpressionUtil.isPolyExpression(myExpression)) {
return true;
}
- if (myExpression instanceof PsiCallExpression) {
- final PsiExpressionList argumentList = ((PsiCallExpression)myExpression).getArgumentList();
- if (argumentList != null) {
- for (PsiExpression expression : argumentList.getExpressions()) {
- if (PsiPolyExpressionUtil.isPolyExpression(expression)) {
- //todo additional constraints [JDK-8033488]
- }
- }
- }
- return true;
- }
if (myExpression instanceof PsiParenthesizedExpression) {
constraints.add(new CheckedExceptionCompatibilityConstraint(((PsiParenthesizedExpression)myExpression).getExpression(), myT));
return true;
@@ -122,7 +111,7 @@ public class CheckedExceptionCompatibilityConstraint extends InputOutputConstrai
final PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor();
final PsiMethod method;
if (((PsiMethodReferenceExpression)myExpression).isExact()) {
- final PsiElement resolve = ((PsiMethodReferenceExpression)myExpression).resolve();
+ final PsiElement resolve = ((PsiMethodReferenceExpression)myExpression).getPotentiallyApplicableMember();
if (resolve instanceof PsiMethod) {
method = (PsiMethod)resolve;
} else {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
index 30628e36beb6..ebcbda6a2926 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
@@ -21,10 +21,13 @@ import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl;
import com.intellij.psi.infos.MethodCandidateInfo;
+import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
+import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -99,22 +102,51 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
if (typeParams != null) {
- for (PsiTypeParameter typeParam : typeParams) {
- session.addCapturedVariable(typeParam);
- }
+ final HashSet<PsiTypeParameter> oldBounds = new HashSet<PsiTypeParameter>(session.getTypeParams());
+ final boolean sameMethodCall = session.initBounds(typeParams);
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
+ final HashSet<InferenceVariable> variables = new HashSet<InferenceVariable>();
+ session.collectDependencies(returnType, variables);
+ final PsiTypeParameter[] params = new PsiTypeParameter[typeParams.length];
+ for (int i = 0; i < typeParams.length; i++) {
+ if (variables.contains(session.getInferenceVariable(typeParams[i]))) {
+ params[i] = JavaPsiFacade.getElementFactory(myExpression.getProject()).createTypeParameterFromText("copyOf" + myExpression.hashCode() + typeParams[i].getName(), null);
+ substitutor = substitutor.put(typeParams[i], JavaPsiFacade.getElementFactory(myExpression.getProject()).createType(params[i]));
+ }
+ else {
+ params[i] = typeParams[i];
+ }
+ }
+ final PsiSubstitutor siteSubstitutor = resolveResult instanceof MethodCandidateInfo && method != null && !method.isConstructor()
+ ? ((MethodCandidateInfo)resolveResult).getSiteSubstitutor() : PsiSubstitutor.EMPTY;
+ for (PsiTypeParameter typeParameter : siteSubstitutor.getSubstitutionMap().keySet()) {
+ substitutor = substitutor.put(typeParameter, substitutor.substitute(siteSubstitutor.substitute(typeParameter)));
+ }
+
+ final Collection<PsiTypeParameter> params1 = session.getTypeParams();
+ final InferenceSession callSession = new InferenceSession(params1.toArray(new PsiTypeParameter[params1.size()]), substitutor, myExpression.getManager(), myExpression);
+ callSession.initBounds(params);
if (method != null) {
- //typeParams are already included
- final Collection<PsiTypeParameter> params = session.getTypeParams();
- InferenceSession callSession = new InferenceSession(params.toArray(new PsiTypeParameter[params.size()]), resolveResult instanceof MethodCandidateInfo ? ((MethodCandidateInfo)resolveResult).getSiteSubstitutor()
- : PsiSubstitutor.EMPTY, myExpression.getManager(), myExpression);
final PsiExpression[] args = argumentList.getExpressions();
final PsiParameter[] parameters = method.getParameterList().getParameters();
callSession.initExpressionConstraints(parameters, args, myExpression, method);
- callSession.registerConstraints(returnType, myT);
- if (callSession.repeatInferencePhases(true)) {
- session.liftBounds(callSession.getInferenceVariables());
+ }
+ final boolean accepted = callSession.repeatInferencePhases(true);
+ if (!accepted) {
+ //todo return false;
+ }
+ callSession.registerConstraints(method != null && !PsiUtil.isRawSubstitutor(method, siteSubstitutor) ? siteSubstitutor.substitute(returnType) : returnType, substitutor.substitute(returnType));
+ if (callSession.repeatInferencePhases(true)) {
+ final Collection<InferenceVariable> inferenceVariables = callSession.getInferenceVariables();
+ if (sameMethodCall) {
+ for (Iterator<InferenceVariable> iterator = inferenceVariables.iterator(); iterator.hasNext(); ) {
+ InferenceVariable variable = iterator.next();
+ if (oldBounds.contains(variable.getParameter())) {
+ iterator.remove();
+ }
+ }
}
+ session.liftBounds(inferenceVariables);
}
final PsiType capturedReturnType = myExpression instanceof PsiMethodCallExpression
? PsiMethodCallExpressionImpl.captureReturnType((PsiMethodCallExpression)myExpression, method, returnType, substitutor)
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java
index 7e2443a8232f..cbb1db809c4a 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeEqualityConstraint.java
@@ -109,6 +109,11 @@ public class TypeEqualityConstraint implements ConstraintFormula {
return true;
}
+ if (myT instanceof PsiCapturedWildcardType && myS instanceof PsiCapturedWildcardType) {
+ return new TypeEqualityConstraint(((PsiCapturedWildcardType)myT).getWildcard(),
+ ((PsiCapturedWildcardType)myS).getWildcard()).reduce(session, constraints);
+ }
+
return false;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java
index 58c29706c1a3..18ff2d110ad9 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java
@@ -25,7 +25,6 @@ import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.CharTable;
import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -55,18 +54,19 @@ public class JavaSharedImplUtil {
return type;
}
+ // collects annotations bound to C-style arrays
private static List<PsiAnnotation[]> collectAnnotations(PsiElement anchor, PsiAnnotation stopAt) {
- List<PsiAnnotation[]> annotations = new SmartList<PsiAnnotation[]>();
+ List<PsiAnnotation[]> annotations = ContainerUtil.newSmartList();
List<PsiAnnotation> current = null;
- boolean stop = false;
+ boolean found = (stopAt == null), stop = false;
for (PsiElement child = anchor.getNextSibling(); child != null; child = child.getNextSibling()) {
if (child instanceof PsiComment || child instanceof PsiWhiteSpace) continue;
if (child instanceof PsiAnnotation) {
- if (current == null) current = new SmartList<PsiAnnotation>();
+ if (current == null) current = ContainerUtil.newSmartList();
current.add((PsiAnnotation)child);
- if (child == stopAt) stop = true;
+ if (child == stopAt) found = stop = true;
continue;
}
@@ -80,8 +80,8 @@ public class JavaSharedImplUtil {
}
}
- // stop == true means annotation is misplaced
- return stop ? null : annotations;
+ // annotation is misplaced (either located before the anchor or has no following brackets)
+ return !found || stop ? null : annotations;
}
public static void normalizeBrackets(@NotNull PsiVariable variable) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java
index f6ba9fdf5af4..918d7fed7237 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.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.
@@ -131,7 +131,7 @@ public class JavaTreeGenerator implements TreeGenerator {
type = PsiType.getJavaLangObject(manager, GlobalSearchScope.projectScope(manager.getProject()));
}
- String text = type.getPresentableText();
+ String text = type.getCanonicalText(true);
PsiJavaParserFacade parserFacade = JavaPsiFacade.getInstance(original.getProject()).getParserFacade();
PsiTypeElement element = parserFacade.createTypeElementFromText(text, original);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.java
index cf40d04ca427..1d8693efc55c 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.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,7 +38,8 @@ public class ExpressionPsiElement extends CompositePsiElement {
@Override
public void replaceChildInternal(@NotNull ASTNode child, @NotNull TreeElement newElement) {
- if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
+ if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType()) &&
+ ElementType.EXPRESSION_BIT_SET.contains(newElement.getElementType())) {
boolean needParenth = ReplaceExpressionUtil.isNeedParenthesis(child, newElement);
if (needParenth) {
newElement = SourceUtil.addParenthToReplacedChild(JavaElementType.PARENTH_EXPRESSION, newElement, getManager());
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 fdd02e86ebb3..084be88d7428 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
@@ -499,6 +499,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
final PsiClass pClass = pResult.getElement();
final PsiSubstitutor receiverSubstitutor = pClass != null ? TypeConversionUtil.getClassSubstitutor(containingClass, pClass, pResult.getSubstitutor()) : null;
if (receiverSubstitutor != null) {
+ if (!method.hasTypeParameters() && signature.getParameterTypes().length == 1) return receiverSubstitutor;
psiSubstitutor = receiverSubstitutor;
}
}
@@ -638,20 +639,26 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
}
}
- checkSpecifics(firstCandidates,
- varargs ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY, myLanguageLevel);
-
- checkSpecifics(secondCandidates,
- varargs ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY, myLanguageLevel);
-
if (myQualifierResolveResult.isReferenceTypeQualified() && getReferenceNameElement() instanceof PsiIdentifier) {
//If the first search produces a static method, and no non-static method is applicable for the second search, then the result of the first search is the compile-time declaration.
- filterStaticCorrectCandidates(firstCandidates, true);
+ CandidateInfo candidateInfo = filterStaticCorrectCandidates(firstCandidates, secondCandidates, true);
+ if (candidateInfo != null) {
+ return candidateInfo;
+ }
//If the second search produces a non-static method, and no static method is applicable for the first search, then the result of the second search is the compile-time declaration.
- filterStaticCorrectCandidates(secondCandidates, false);
+ candidateInfo = filterStaticCorrectCandidates(secondCandidates, firstCandidates, false);
+ if (candidateInfo != null) {
+ return candidateInfo;
+ }
}
+ checkSpecifics(firstCandidates,
+ varargs ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY, myLanguageLevel);
+
+ checkSpecifics(secondCandidates,
+ varargs ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY, myLanguageLevel);
+
final int acceptedCount = firstCandidates.size() + secondCandidates.size();
if (acceptedCount == 1) {
return !firstCandidates.isEmpty() ? firstCandidates.get(0) : secondCandidates.get(0);
@@ -684,17 +691,29 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
/**
* 15.13.1
*/
- private void filterStaticCorrectCandidates(List<CandidateInfo> firstCandidates,
+ private CandidateInfo filterStaticCorrectCandidates(List<CandidateInfo> firstCandidates,
+ List<CandidateInfo> secondCandidates,
boolean shouldBeStatic) {
- for (Iterator<CandidateInfo> iterator = firstCandidates.iterator(); iterator.hasNext(); ) {
- final PsiElement element = iterator.next().getElement();
+ if (firstCandidates.size() == 1) {
+ final CandidateInfo candidateInfo = firstCandidates.get(0);
+ final PsiElement element = candidateInfo.getElement();
if (element instanceof PsiMethod) {
final boolean isStatic = ((PsiMethod)element).hasModifierProperty(PsiModifier.STATIC);
- if (shouldBeStatic && !isStatic || !shouldBeStatic && isStatic) {
- iterator.remove();
+ if (shouldBeStatic && isStatic || !shouldBeStatic && !isStatic) {
+ for (CandidateInfo secondCandidate : secondCandidates) {
+ final PsiElement psiElement = secondCandidate.getElement();
+ if (psiElement instanceof PsiMethod) {
+ final boolean oppositeStatic = ((PsiMethod)psiElement).hasModifierProperty(PsiModifier.STATIC);
+ if (shouldBeStatic && !oppositeStatic || !shouldBeStatic && oppositeStatic) {
+ return null;
+ }
+ }
+ }
+ return candidateInfo;
}
}
}
+ return null;
}
private boolean isCorrectAssignment(PsiType[] signatureParameterTypes2,
diff --git a/java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping.java b/java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping.java
new file mode 100644
index 000000000000..00d3186f4ef2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping.java
@@ -0,0 +1,4 @@
+class Foo {{
+ System.out.p<caret>
+ System.out.p<caret>
+}}
diff --git a/java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping_after.java b/java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping_after.java
new file mode 100644
index 000000000000..87debd854955
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/MulticaretTyping_after.java
@@ -0,0 +1,4 @@
+class Foo {{
+ System.out.append(<caret>)
+ System.out.append(<caret>)
+}}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/UnsupportedFeatures7.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/UnsupportedFeatures7.java
index 506accd112c3..d0d4dbc5324a 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/UnsupportedFeatures7.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/UnsupportedFeatures7.java
@@ -27,7 +27,7 @@ class UnsupportedFeatures {
for (String s : args) { System.out.println(s); }
List<String> list =
- new ArrayList<>();
+ new ArrayList<error descr="Diamond types are not supported at this language level"><></error>();
for (String s : list) {}
Arrays.asList("");
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondMisc.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondMisc.java
index f51647ab0a23..fbbe91649ddb 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondMisc.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondMisc.java
@@ -97,14 +97,14 @@ interface I<T> {
class FI1 {
I<? extends String> i1 = new I<<error descr="Cannot use ''<>'' with anonymous inner classes"></error>>() {
@Override
- public <error descr="'m()' in 'Anonymous class derived from I' clashes with 'm()' in 'I'; attempting to use incompatible return type">String</error> m() {
+ public String m() {
return null;
}
};
I<?> i2 = new I<<error descr="Cannot use ''<>'' with anonymous inner classes"></error>>() {
@Override
- public <error descr="'m()' in 'Anonymous class derived from I' clashes with 'm()' in 'I'; attempting to use incompatible return type">Object</error> m() {
+ public Object m() {
return null;
}
};
@@ -157,14 +157,14 @@ class ParenthTest<T extends TZ> {
class TestWildcardInference {
interface A<T> {
}
-
+
class B<V> implements A<V> {
B(C<V> v) {
}
}
-
+
class C<E> {}
-
+
class U {
void foo() {
C<? extends Number> x = null;
@@ -202,13 +202,13 @@ class Another {
System.out.println(i);
- <error descr="Incompatible types. Found: 'Outer2.Inner2<java.lang.String>', required: 'Outer2.Inner2<java.lang.String>'">Outer2<Integer>.Inner2<String> i5 = new Outer2<>().new Inner2<>();</error>
+ <error descr="Incompatible types. Found: 'Outer2.Inner2<java.lang.String>', required: 'Outer2<java.lang.Integer>.Inner2<java.lang.String>'">Outer2<Integer>.Inner2<String> i5 = new Outer2<>().new Inner2<>();</error>
}
static Outer m() {return null;}
static <T extends Outer> T m1() {return null;}
static <T> T m2() {return null;}
-
+
}
class TypeParamsExtendsList {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java
index 400a678da1ed..28035c8c1698 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java
@@ -111,6 +111,7 @@ class Outer {
int @TA [] a @TA [] <error descr="Annotations are not allowed here">@TA</error> = (p != null ? p : mixedArrays);
return a;
}
+ void <error descr="Annotations are not allowed here">@TA</error> misplaced() { }
@TA Outer() { }
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java
index 7236a9bcec95..de27a241d858 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA57413.java
@@ -2,6 +2,6 @@ class A<T> {
<T extends A<T>> void foo(T x){}
void bar(A<?> x){
- <error descr="Inferred type 'A<capture<?>>' for type parameter 'T' is not within its bound; should extend 'A<A<capture<?>>>'">foo(x)</error>;
+ <error descr="Inferred type 'capture<?>' for type parameter 'T' is not within its bound; should extend 'A<capture<? extends A<capture<?>>>>'">foo(x)</error>;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java
index 7556292ef538..298a33dcbdf6 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/Variance.java
@@ -142,7 +142,7 @@ class S1 {
}
void bar(List<? extends S1> k) {
- f<error descr="'f(java.util.List<capture<? extends S1>>, capture<? extends S1>)' in 'S1' cannot be applied to '(java.util.List<capture<? extends S1>>, S1)'">(k, k.get(0))</error>;
+ f<error descr="'f(java.util.List<capture<? extends S1>>, capture<? extends S1>)' in 'S1' cannot be applied to '(java.util.List<capture<? extends S1>>, capture<? extends S1>)'">(k, k.get(0))</error>;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/LiftedCaptureToOuterCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/LiftedCaptureToOuterCall.java
new file mode 100644
index 000000000000..75d3b8ab6123
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/LiftedCaptureToOuterCall.java
@@ -0,0 +1,16 @@
+class Test {
+
+ class Foo<K> {}
+
+ void test(Foo<? extends String> p) {
+ foo(bar(p)) ;
+ }
+
+ <T> T bar(Foo<T> p) {
+ return null;
+ }
+
+ <K> K foo(K p) {
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCallsSameMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCallsSameMethod.java
index eaafb1b96716..458171f5b51a 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCallsSameMethod.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCallsSameMethod.java
@@ -1,3 +1,41 @@
+import java.util.List;
+
+import java.util.function.Function;
+
+abstract class Main2 {
+ void address(Foo sa) {
+ String ds = foobar(foobar(sa, Foo::getBar), Bar ::getName);
+ Function<Foo, Bar> f = null;
+ String ds1 = foobar(foobar(sa, f), null);
+ }
+
+ abstract <T, V> V foobar(T t, Function<T, V> mapper);
+
+ class Foo {
+ Bar getBar() {
+ return new Bar();
+ }
+ }
+
+ class Bar {
+ String getName(){
+ return null;
+ }
+ }
+}
+
+
+class Main0 {
+ <T> List<T> foo(T t){
+ return null;
+ }
+
+ {
+ foo(foo(""));
+ }
+}
+
+
class Main {
static <T> T foo(T t) { return null; }
@@ -14,6 +52,6 @@ class Main1 {
static <B> B bar(B t) { return null;}
static {
- long l = foo(bar(1));
+ //long l = foo(bar(1));
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SiteSubstitutionForReturnConstraint.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SiteSubstitutionForReturnConstraint.java
new file mode 100644
index 000000000000..ca5ad38ddfab
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/SiteSubstitutionForReturnConstraint.java
@@ -0,0 +1,21 @@
+import java.util.function.Function;
+import java.util.stream.Collector;
+
+class Collectors {
+
+ public static <A,R,RR> void collectingAndThen(Function<R, RR> finisher, Function<A, R> finisher1) {
+ Function<A, RR> f = finisher1.andThen(finisher);
+ }
+
+}
+
+
+class Collectors1 {
+ public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Function<R, RR> finisher, Function<A, R> function) {
+ return factory(function.andThen(finisher));
+ }
+
+ static <Ts, As, Rs> Collector<Ts, As, Rs> factory(Function<As, Rs> f) {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeAmbiguity.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeAmbiguity.java
index 8ee9852f366f..70a6e70c310c 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeAmbiguity.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeAmbiguity.java
@@ -40,6 +40,6 @@ class AAmbiguous {
}
public static void main(Promise<String> helloWorld) {
- helloWorld.then<error descr="Ambiguous method call: both 'Promise.then(Function<? super String,Promise<Integer>>)' and 'Promise.then(AsyncFunction<? super String,Promise<Integer>>)' match">(AAmbiguous::calculateLength)</error>;
+ helloWorld.then<error descr="Ambiguous method call: both 'Promise.then(Function<? super String, Promise<Integer>>)' and 'Promise.then(AsyncFunction<? super String, Promise<Integer>>)' match">(AAmbiguous::calculateLength)</error>;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java
index 84e929697a92..d62afb3fdfcd 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java
@@ -21,9 +21,9 @@ class Test {
}
void foo(Foo<String> as, final Foo<Character> ac) {
- boolean b1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> false)</error>);
- String s1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> "")</error>);
- boolean b2 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> "")</error>);
+ boolean b1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> false)</error>);
+ String s1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> "")</error>);
+ boolean b2 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> "")</error>);
String s2 = as.forAll2(s -> ac.forAll2(<error descr="Incompatible return type boolean in lambda expression">c -> false</error>));
boolean b3 = as.forAll((I<String, Boolean>)s -> ac.forAll((I<Character, Boolean>)<error descr="Incompatible return type String in lambda expression">c -> ""</error>));
String s3 = as.forAll((II<String, String>)s -> ac.forAll((II<Character, String>)<error descr="Incompatible return type boolean in lambda expression">c -> false</error>));
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java
index cb671b7cd6c0..84b2259286fa 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java
@@ -2,4 +2,5 @@ interface A {
default String <error descr="Default method 'toString' overrides a member of 'java.lang.Object'">toString</error>() {
return "";
}
+ default void finalize() throws Throwable { }
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java
index 40811fd1f7a7..bc235b224c31 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java
@@ -29,7 +29,7 @@ class AlienTest {
<error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IInt'">IInt i2 = MyTest::foo;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IInt'">IInt i3 = MyTest::bar;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IIntInt'">IIntInt i4 = MyTest::bar;</error>
- <error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IInt'">IInt i5 = MyTest::baz;</error>
+ IInt i5 = <error descr="Non-static method cannot be referenced from a static context">MyTest::baz</error>;
IInt i6 = <error descr="'foo(int)' is not public in 'MyTest.Foo'. Cannot be accessed from outside package">MyTest.foo::foo</error>;
IInt i7 = MyTest.<error descr="'MyTest.Foo' has private access in 'MyTest'">Foo</error>::foo;
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java
index 848c423302c6..0696aadf6179 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java
@@ -29,7 +29,7 @@ class MyTest {
}
public static void main(String[] args) {
- foo<error descr="Ambiguous method call: both 'MyTest.foo(I1)' and 'MyTest.foo(I2)' match">(Foo::m)</error>;
+ foo<error descr="Ambiguous method call: both 'MyTest.foo(I2)' and 'MyTest.foo(I3)' match">(Foo::m)</error>;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/StaticProblems.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/StaticProblems.java
index 3375ceb2a090..8d482f2920ab 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/StaticProblems.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/StaticProblems.java
@@ -41,14 +41,14 @@ class MyTest1 {
static void call2(I2 s) { }
static void test1() {
- <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I1'">I1 s1 = MyTest1 ::m1;</error>
- call1<error descr="'call1(MyTest1.I1)' in 'MyTest1' cannot be applied to '(<method reference>)'">(MyTest1::m1)</error>;
+ I1 s1 = <error descr="Non-static method cannot be referenced from a static context">MyTest1 ::m1</error>;
+ call1(<error descr="Non-static method cannot be referenced from a static context">MyTest1::m1</error>);
I1 s2 = MyTest1 :: m2;
call1(MyTest1::m2);
I1 s3 = MyTest1::m3;
call1(MyTest1::m3);
- <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I1'">I1 s4 = MyTest1::m4;</error>
- call1<error descr="'call1(MyTest1.I1)' in 'MyTest1' cannot be applied to '(<method reference>)'">(MyTest1::m4)</error>;
+ I1 s4 = <error descr="Non-static method cannot be referenced from a static context">MyTest1::m4</error>;
+ call1(<error descr="Non-static method cannot be referenced from a static context">MyTest1::m4</error>);
}
static void test2() {
@@ -90,14 +90,14 @@ class MyTest2 {
static void call2(I2 s) { }
static void test1() {
- <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest2.I1'">I1 s1 = MyTest2 ::m1;</error>
- call1<error descr="'call1(MyTest2.I1)' in 'MyTest2' cannot be applied to '(<method reference>)'">(MyTest2::m1)</error>;
+ I1 s1 = <error descr="Non-static method cannot be referenced from a static context">MyTest2 ::m1</error>;
+ call1(<error descr="Non-static method cannot be referenced from a static context">MyTest2::m1</error>);
I1 s2 = MyTest2 :: m2;
call1(MyTest2::m2);
I1 s3 = MyTest2::m3;
call1(MyTest2::m3);
- <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest2.I1'">I1 s4 = MyTest2::m4;</error>
- call1<error descr="'call1(MyTest2.I1)' in 'MyTest2' cannot be applied to '(<method reference>)'">(MyTest2::m4)</error>;
+ I1 s4 = <error descr="Non-static method cannot be referenced from a static context">MyTest2::m4</error>;
+ call1(<error descr="Non-static method cannot be referenced from a static context">MyTest2::m4</error>);
}
static void test2() {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/Varargs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/Varargs.java
index 66f4e0701b4b..e521df2c2d40 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/Varargs.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/Varargs.java
@@ -55,7 +55,7 @@ class MyTest {
{
- <error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_1 = MyTest::_1;</error>
+ I1 i_1 = <error descr="Non-static method cannot be referenced from a static context">MyTest::_1</error>;
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_2 = MyTest::_2;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_3 = MyTest::_3;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_4 = MyTest::_4;</error>
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsInReceiverPosition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsInReceiverPosition.java
index f6c1e3f67c0e..cf2151dc76d8 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsInReceiverPosition.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsInReceiverPosition.java
@@ -3,7 +3,7 @@ import java.util.*;
class Test {
void test() {
Comparator<Test> r2 = Test::yyy;
- <error descr="Incompatible types. Found: '<method reference>', required: 'Comparator1<Test>'">Comparator1<Test> c1 = Test::yyy;</error>
+ Comparator1<Test> c1 = <error descr="Non-static method cannot be referenced from a static context">Test::yyy</error>;
<error descr="Incompatible types. Found: '<method reference>', required: 'Comparator1<Test>'">Comparator1<Test> c2 = Test::xxx;</error>
}
int yyy(Test... p) { return 1; }
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/DiamondInLambdaReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/DiamondInLambdaReturn.java
new file mode 100644
index 000000000000..8f547d2038ba
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/DiamondInLambdaReturn.java
@@ -0,0 +1,9 @@
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+class Test {
+ Set<String> collect(Stream<String> map){
+ return map.collect(Collectors.toCollection(() -> new LinkedHashSet<>()));
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA118965.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA118965.java
new file mode 100644
index 000000000000..207a091eb3c6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA118965.java
@@ -0,0 +1,37 @@
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import static java.util.Arrays.asList;
+
+class Test {
+
+ public static void main(String[] args) {
+
+ List<String> list = new ArrayList<>(); // JDK 7 diamond operator
+ list.add("aaa");
+ list.add("bb");
+ list.add("cccc");
+ list.add("dd");
+ list.add("e");
+
+ schwartz(list.stream(), s -> s.length())
+ .forEach(x -> { System.out.println(x); });
+ }
+
+ public static<T, R extends Comparable<? super R>> Stream<T> schwartz(Stream<T> stream, Function<T, R> f) {
+
+ // class Pair - type of second element of pair must be Comparable
+ final class Pair<F, S extends Comparable<? super S>> {
+ public final F first;
+ public final S second;
+ public Pair(F first, S second){ this.first = first; this.second = second; }
+ }
+
+ return stream
+ .map(t -> new Pair<>(t, f.apply(t)))
+ .sorted((p1, p2) -> p1.second.compareTo(p2.second))
+ .map(p -> p.first);
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialApplicability.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialApplicability.java
index ab7614c23c55..18f5026255c6 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialApplicability.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialApplicability.java
@@ -53,7 +53,7 @@ class Test {
Test s1 = staticCall(Test::n0);
Test s2 = staticCall(Test::n1);
Test s3 = staticCall<error descr="Cannot resolve method 'staticCall(<method reference>)'">(Test::n2)</error>;
- Test s4 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test,String>)' match">(Test::n01)</error>;
- Test s5 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test,String>)' match">(Test::n012)</error>;
+ Test s4 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test, String>)' match">(Test::n01)</error>;
+ Test s5 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test, String>)' match">(Test::n012)</error>;
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/ReturnTypeCheckForRawReceiver.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/ReturnTypeCheckForRawReceiver.java
new file mode 100644
index 000000000000..853b02ada009
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/ReturnTypeCheckForRawReceiver.java
@@ -0,0 +1,15 @@
+class Test {
+
+ static class Foo<X> {
+ X m() { return null;}
+ }
+
+ interface I {
+ Foo<Object> _i(Foo<String> fs);
+ }
+
+ static void foo(I i) { }
+ {
+ foo(<error descr="Bad return type in method reference: cannot convert java.lang.String to Test.Foo<java.lang.Object>">Foo::m</error>);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/StaticNonStaticReferenceTypeAmbiguity.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/StaticNonStaticReferenceTypeAmbiguity.java
new file mode 100644
index 000000000000..7430c7c889e9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/StaticNonStaticReferenceTypeAmbiguity.java
@@ -0,0 +1,15 @@
+class Test {
+
+ interface I {
+ void m(Test rec, String s);
+ }
+
+ void m(Test t, String s) {}
+ void m(String s) {}
+
+ static void m(Test t, Object s) {}
+
+ static void test() {
+ <error descr="Incompatible types. Found: '<method reference>', required: 'Test.I'">I i = Test::m;</error>
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/LambdaFormalParamTypesParametrization.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/LambdaFormalParamTypesParametrization.java
new file mode 100644
index 000000000000..0dbcc3e35fec
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/LambdaFormalParamTypesParametrization.java
@@ -0,0 +1,10 @@
+import java.util.function.Function;
+
+class Test {
+
+ <U, V> void foo(Function<U, ? extends V> m) {}
+
+ {
+ foo((String e) -> e.length());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/NonWildcardParametrization.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/NonWildcardParametrization.java
new file mode 100644
index 000000000000..fa9df550e936
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/NonWildcardParametrization.java
@@ -0,0 +1,108 @@
+import java.util.List;
+
+class SimpleDependency {
+
+ interface I<R extends U, U> {
+ R m();
+ }
+
+ {
+ I<? extends String, ? extends String> k = () -> null;
+ I<? extends String, String> k1 = () -> null;
+ I<? extends List<String>, List<String>> k2 = () -> null;
+ I<? extends List<String>, ? extends List<String>> k3 = () -> null;
+ I<? extends List<? extends String>, ? extends List<String>> k4 = <error descr="Cannot infer functional interface type">() -> null</error>;
+ I<? extends List<? extends String>, List<? extends String>> k5 = () -> null;
+ I<? extends List<? extends String>, ? extends List<? extends String>> k6 = () -> null;
+
+ I<? super String, String> s = () -> null;
+ I<? super List<String>, List<? extends String>> s1 = () -> null;
+ }
+}
+
+class NoDependency {
+ interface I<T, U> {
+ T m();
+ }
+
+ {
+ I<? extends String, ? extends String> k = () -> null;
+ }
+}
+
+class ExtendsList {
+ interface I<R extends List<T>, T> {
+ R m();
+ }
+
+ {
+ I<?, ? extends String> n = <error descr="Cannot infer functional interface type">() -> null</error>;
+ I<?, ?> n1 = <error descr="Cannot infer functional interface type">() -> null</error>;
+ I<?, String> n2 = <error descr="Cannot infer functional interface type">() -> null</error>;
+
+
+ I<? extends List<?>, String> e1 = <error descr="Cannot infer functional interface type">() -> null</error>;
+ I<? extends List<?>, ?> e2 = <error descr="Cannot infer functional interface type">() -> null</error>;
+ I<? extends List<String>, ? extends String> e3 = () -> null;
+ I<? extends List<? extends String>, ? extends String> e4 = <error descr="Cannot infer functional interface type">() -> null</error>;
+
+ I<? super List<String>, ? extends String> s1 = () -> null;
+ I<? super List<String>, String> s2 = () -> null;
+ }
+}
+
+class MultipleBounds {
+ interface I<R extends List<T> & Comparable<T>, T> {
+ R m();
+ }
+
+ interface LC<K> extends List<K>, Comparable<K> {}
+
+ {
+ I<?, String> n = <error descr="Cannot infer functional interface type">() -> null</error>;
+
+ I<? extends List<String>, ? extends String> e1 = <error descr="Cannot infer functional interface type">() -> null</error>;
+ I<? extends Comparable<String>, ? extends String> e2 = <error descr="Cannot infer functional interface type">() -> null</error>;
+ I<? extends LC<String>, ? extends String> e3 = () -> null;
+ I<? extends LC<String>, String> e4 = () -> null;
+ I<? extends LC<? extends String>, String> e5 = <error descr="Cannot infer functional interface type">() -> null</error>;
+ }
+}
+
+class FirstIndependentBound {
+ interface I<R extends List<String> & Comparable<T>, T> {
+ R m();
+ }
+
+ interface LC<K> extends List<String>, Comparable<K> {}
+
+ {
+ I<?, String> n = <error descr="Cannot infer functional interface type">() -> null</error>;
+
+ I<? extends List<String>, ? extends String> e1 = <error descr="Cannot infer functional interface type">() -> null</error>;
+ I<? extends Comparable<String>, ? extends String> e2 = () -> null;
+ I<? extends LC<String>, ? extends String> e3 = () -> null;
+ I<? extends LC<String>, String> e4 = () -> null;
+ I<? extends LC<? extends String>, String> e5 = <error descr="Cannot infer functional interface type">() -> null</error>;
+ }
+}
+
+
+class SecondIndependentBound {
+ interface I<R extends List<T> & Comparable<String>, T> {
+ R m();
+ }
+
+ interface LC<K> extends List<String>, Comparable<K> {}
+
+ {
+ I<?, String> n = <error descr="Cannot infer functional interface type">() -> null</error>;
+
+ I<? extends List<String>, ? extends String> e1 = () -> null;
+ I<? extends Comparable<String>, ? extends String> e2 = <error descr="Cannot infer functional interface type">() -> null</error>;
+ I<? extends LC<String>, ? extends String> e3 = () -> null;
+ I<? extends LC<String>, String> e4 = () -> null;
+ I<? extends LC<? extends String>, String> e5 = <error descr="Cannot infer functional interface type">() -> null</error>;
+ I<? extends LC<? extends String>, ? extends String> e6 = <error descr="Cannot infer functional interface type">() -> null</error>;
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/PrimitiveParameterTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/PrimitiveParameterTypes.java
new file mode 100644
index 000000000000..f339392c1bee
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization/PrimitiveParameterTypes.java
@@ -0,0 +1,13 @@
+class IDEA100385 {
+ void foo(N<Double> n){
+ n.forEach((<error descr="Incompatible parameter types in lambda expression">double e</error>) -> { });
+ }
+ static interface N<E> {
+ void forEach(Consumer<? extends E> consumer);
+ }
+
+ interface Consumer<T> {
+ public void accept(T t);
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterEnumConstantWithoutClassInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterEnumConstantWithoutClassInitializer.java
index 9ae8bed1d285..2369d9c9d05d 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterEnumConstantWithoutClassInitializer.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterEnumConstantWithoutClassInitializer.java
@@ -1,9 +1,11 @@
// "Implement Methods" "true"
enum E {
- A {
- public void foo() {
-
- }
- };
- abstract void foo();
+ A {
+ @Override
+ public int foo() {
+ return 0;
+ }
+ };
+
+ public abstract int foo();
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterIDEA108454.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterIDEA108454.java
new file mode 100644
index 000000000000..a7e8482f6d42
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/afterIDEA108454.java
@@ -0,0 +1,17 @@
+// "Implement Methods" "true"
+class Test {
+ class A<T> {
+ public class Inner { }
+ }
+
+ interface B<T> {
+ T foo();
+ }
+
+ class D implements B<A<String>.Inner> {
+ @Override
+ public A<String>.Inner foo() {
+ return null;
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeEnumConstantWithoutClassInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeEnumConstantWithoutClassInitializer.java
index 92bbb6aea212..518de23ab0c6 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeEnumConstantWithoutClassInitializer.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeEnumConstantWithoutClassInitializer.java
@@ -1,5 +1,6 @@
// "Implement Methods" "true"
enum E {
- <caret>A;
- public abstract void foo();
+ <caret>A;
+
+ public abstract int foo();
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeIDEA108454.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeIDEA108454.java
new file mode 100644
index 000000000000..32e8e5b5f4f4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/implementMethods/beforeIDEA108454.java
@@ -0,0 +1,12 @@
+// "Implement Methods" "true"
+class Test {
+ class A<T> {
+ public class Inner { }
+ }
+
+ interface B<T> {
+ T foo();
+ }
+
+ <caret>class D implements B<A<String>.Inner> { }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayList.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayList.java
new file mode 100644
index 000000000000..aef9e753f716
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayList.java
@@ -0,0 +1,15 @@
+// "Replace with collect" "true"
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons){
+ List<String> names = persons.stream().map(Person::getName).collect(Collectors.toList());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListAndFilter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListAndFilter.java
new file mode 100644
index 000000000000..4467078950cd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListAndFilter.java
@@ -0,0 +1,15 @@
+// "Replace with collect" "true"
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons){
+ List<String> names = persons.stream().filter(person -> person != null).map(Person::getName).collect(Collectors.toList());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListLambda.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListLambda.java
new file mode 100644
index 000000000000..e1517740be28
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListLambda.java
@@ -0,0 +1,15 @@
+// "Replace with collect" "true"
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons){
+ List<String> names = persons.stream().map(person -> "name: " + person.getName()).collect(Collectors.toList());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSet.java
new file mode 100644
index 000000000000..022b8e3ae576
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSet.java
@@ -0,0 +1,15 @@
+// "Replace with collect" "true"
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons){
+ Set<String> names = persons.stream().map(Person::getName).collect(Collectors.toSet());
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSetFieldInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSetFieldInitializer.java
new file mode 100644
index 000000000000..edd903ab1769
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSetFieldInitializer.java
@@ -0,0 +1,16 @@
+// "Replace with collect" "true"
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ Set<String> names = new HashSet<>();
+ void collectNames(List<Person> persons){
+ names.addAll(persons.stream().map(Person::getName).collect(Collectors.toList()));
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectLinkedHashSet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectLinkedHashSet.java
new file mode 100644
index 000000000000..6bb6839b0cea
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectLinkedHashSet.java
@@ -0,0 +1,15 @@
+// "Replace with collect" "true"
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons){
+ Set<String> names = persons.stream().map(Person::getName).collect(Collectors.toCollection(() -> new LinkedHashSet<>()));
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSelfCollection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSelfCollection.java
new file mode 100644
index 000000000000..676c127d4a6f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSelfCollection.java
@@ -0,0 +1,15 @@
+// "Replace with collect" "true"
+import java.util.*;
+import java.util.stream.Collectors;
+
+public abstract class Collect implements Collection<String>{
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons){
+ addAll(persons.stream().map(Person::getName).collect(Collectors.toList()));
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSetParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSetParameter.java
new file mode 100644
index 000000000000..c8201c9b486e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSetParameter.java
@@ -0,0 +1,15 @@
+// "Replace with collect" "true"
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons, Set<String> names){
+ names.addAll(persons.stream().map(Person::getName).collect(Collectors.toList()));
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterNoBraces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterNoBraces.java
new file mode 100644
index 000000000000..ab67b49343ca
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterNoBraces.java
@@ -0,0 +1,10 @@
+// "Replace with forEach" "true"
+import java.util.ArrayList;
+import java.util.List;
+
+class Sample {
+ List<String> foo = new ArrayList<>();
+ {
+ foo.stream().filter(s -> s != null).forEach(System.out::println);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterNormalNoBraces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterNormalNoBraces.java
new file mode 100644
index 000000000000..b7c6bdeca41d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterNormalNoBraces.java
@@ -0,0 +1,10 @@
+// "Replace with forEach" "true"
+import java.util.ArrayList;
+import java.util.List;
+
+class Sample {
+ List<String> foo = new ArrayList<>();
+ {
+ foo.forEach(System.out::println);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayList.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayList.java
new file mode 100644
index 000000000000..3114dd720dd3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayList.java
@@ -0,0 +1,17 @@
+// "Replace with collect" "true"
+import java.util.*;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons){
+ List<String> names = new ArrayList<>();
+ for (Person person : pers<caret>ons) {
+ names.add(person.getName());
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListAndFilter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListAndFilter.java
new file mode 100644
index 000000000000..9a671cbafd0b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListAndFilter.java
@@ -0,0 +1,19 @@
+// "Replace with collect" "true"
+import java.util.*;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons){
+ List<String> names = new ArrayList<>();
+ for (Person person : pers<caret>ons) {
+ if (person != null) {
+ names.add(person.getName());
+ }
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListLambda.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListLambda.java
new file mode 100644
index 000000000000..434c2c5a1bec
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListLambda.java
@@ -0,0 +1,17 @@
+// "Replace with collect" "true"
+import java.util.*;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons){
+ List<String> names = new ArrayList<>();
+ for (Person person : pers<caret>ons) {
+ names.add("name: " + person.getName());
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSet.java
new file mode 100644
index 000000000000..9e1e0e52659d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSet.java
@@ -0,0 +1,17 @@
+// "Replace with collect" "true"
+import java.util.*;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons){
+ Set<String> names = new HashSet<>();
+ for (Person person : pers<caret>ons) {
+ names.add(person.getName());
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSetFieldInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSetFieldInitializer.java
new file mode 100644
index 000000000000..44f39e19f3dc
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSetFieldInitializer.java
@@ -0,0 +1,17 @@
+// "Replace with collect" "true"
+import java.util.*;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ Set<String> names = new HashSet<>();
+ void collectNames(List<Person> persons){
+ for (Person person : pers<caret>ons) {
+ names.add(person.getName());
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectLinkedHashSet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectLinkedHashSet.java
new file mode 100644
index 000000000000..f3ffecc179d0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectLinkedHashSet.java
@@ -0,0 +1,17 @@
+// "Replace with collect" "true"
+import java.util.*;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons){
+ Set<String> names = new LinkedHashSet<>();
+ for (Person person : pers<caret>ons) {
+ names.add(person.getName());
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSelfCollection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSelfCollection.java
new file mode 100644
index 000000000000..1dbed313c132
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSelfCollection.java
@@ -0,0 +1,16 @@
+// "Replace with collect" "true"
+import java.util.*;
+
+public abstract class Collect implements Collection<String>{
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons){
+ for (Person person : pers<caret>ons) {
+ add(person.getName());
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSetParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSetParameter.java
new file mode 100644
index 000000000000..f7287c4b9a56
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSetParameter.java
@@ -0,0 +1,16 @@
+// "Replace with collect" "true"
+import java.util.*;
+
+public class Collect {
+ class Person {
+ String getName() {
+ return "";
+ }
+ }
+
+ void collectNames(List<Person> persons, Set<String> names){
+ for (Person person : pers<caret>ons) {
+ names.add(person.getName());
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFilterNoBraces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFilterNoBraces.java
new file mode 100644
index 000000000000..8c712761fb28
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFilterNoBraces.java
@@ -0,0 +1,12 @@
+// "Replace with forEach" "true"
+import java.util.ArrayList;
+import java.util.List;
+
+class Sample {
+ List<String> foo = new ArrayList<>();
+ {
+ for (String s : fo<caret>o) {
+ if (s != null) System.out.println(s);
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeNormalNoBraces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeNormalNoBraces.java
new file mode 100644
index 000000000000..0ad984469b06
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeNormalNoBraces.java
@@ -0,0 +1,10 @@
+// "Replace with forEach" "true"
+import java.util.ArrayList;
+import java.util.List;
+
+class Sample {
+ List<String> foo = new ArrayList<>();
+ {
+ for (String s : fo<caret>o) System.out.println(s);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/gotosuper/Lambda.after.java b/java/java-tests/testData/codeInsight/gotosuper/Lambda.after.java
new file mode 100644
index 000000000000..2fe10c280c86
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/gotosuper/Lambda.after.java
@@ -0,0 +1,9 @@
+interface I {
+ void <caret>run();
+}
+
+class Foo {
+ {
+ I i = () -> {};
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/gotosuper/Lambda.java b/java/java-tests/testData/codeInsight/gotosuper/Lambda.java
new file mode 100644
index 000000000000..26c024317a1d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/gotosuper/Lambda.java
@@ -0,0 +1,9 @@
+interface I {
+ void run();
+}
+
+class Foo {
+ {
+ I i = ()<caret> -> {};
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/gotosuper/LambdaMarker.java b/java/java-tests/testData/codeInsight/gotosuper/LambdaMarker.java
new file mode 100644
index 000000000000..26c024317a1d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/gotosuper/LambdaMarker.java
@@ -0,0 +1,9 @@
+interface I {
+ void run();
+}
+
+class Foo {
+ {
+ I i = ()<caret> -> {};
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/fileEditorManager/src/Bar.java b/java/java-tests/testData/fileEditorManager/src/Bar.java
new file mode 100644
index 000000000000..4843c680a616
--- /dev/null
+++ b/java/java-tests/testData/fileEditorManager/src/Bar.java
@@ -0,0 +1,5 @@
+public class Bar {
+ public String doIt() {
+ return "";
+ }
+}
diff --git a/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef.java b/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef.java
index b06887668d65..ded427d4aef0 100644
--- a/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef.java
+++ b/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef.java
@@ -1,15 +1,12 @@
-import java.lang.annotation.*;
-import static java.lang.annotation.ElementType.*;
-
-@Target({TYPE_USE}) @interface TA { }
+import pkg.TA;
class Outer {
class Middle {
class Inner {
void m1(Outer.Middle.Inner p) { }
- void m2(@TA Outer.Middle.Inner p) { }
- void m3(Outer.@TA Middle.Inner p) { }
- void m4(Outer.Middle.@TA @TA Inner p) { }
+ void m2(@pkg.TA Outer.Middle.Inner p) { }
+ void m3(Outer.@pkg.TA Middle.Inner p) { }
+ void m4(Outer.Middle.@pkg.TA @pkg.TA Inner p) { }
}
}
}
diff --git a/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef_after.java b/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef_after.java
index 1c4c8d4a3ec5..fab10a32c52f 100644
--- a/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef_after.java
+++ b/java/java-tests/testData/psi/shortenClassRefs/TypeAnnotatedRef_after.java
@@ -1,7 +1,4 @@
-import java.lang.annotation.*;
-import static java.lang.annotation.ElementType.*;
-
-@Target({TYPE_USE}) @interface TA { }
+import pkg.TA;
class Outer {
class Middle {
diff --git a/java/java-tests/testData/psi/shortenClassRefs/pkg/TA.java b/java/java-tests/testData/psi/shortenClassRefs/pkg/TA.java
new file mode 100644
index 000000000000..abe2aca8d7ac
--- /dev/null
+++ b/java/java-tests/testData/psi/shortenClassRefs/pkg/TA.java
@@ -0,0 +1,6 @@
+package pkg;
+
+import java.lang.annotation.*;
+
+@Target({ElementType.TYPE_USE})
+@interface TA { }
diff --git a/java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java b/java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java
index 38d94b3a880b..c98b7fa857fc 100644
--- a/java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java
+++ b/java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java
@@ -2,6 +2,6 @@ import util.Pair;
class Client {
void method() {
- Pair<String, Pair<Integer,Boolean>> p = PairProvider.getPair();
+ Pair<String, Pair<Integer, Boolean>> p = PairProvider.getPair();
}
} \ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java
index 231a0cd45c0a..ec8b8dd49284 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java
@@ -27,7 +27,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.command.WriteCommandAction;
-import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.module.Module;
@@ -51,6 +50,7 @@ import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.testFramework.fixtures.*;
+import com.intellij.util.ObjectUtils;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -122,13 +122,7 @@ public class AddAnnotationFixTest extends UsefulTestCase {
@NotNull
private PsiModifierListOwner getOwner() {
- CaretModel caretModel = myFixture.getEditor().getCaretModel();
- int position = caretModel.getOffset();
- PsiElement element = myFixture.getFile().findElementAt(position);
- assert element != null;
- PsiModifierListOwner container = AddAnnotationPsiFix.getContainer(element);
- assert container != null;
- return container;
+ return ObjectUtils.assertNotNull(AddAnnotationPsiFix.getContainer(myFixture.getFile(), myFixture.getCaretOffset()));
}
private void startListening(@NotNull final List<Trinity<PsiModifierListOwner, String, Boolean>> expectedSequence) {
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/ImplementMethodsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/ImplementMethodsTest.java
index b5ab59a09c2a..6fd655344758 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/ImplementMethodsTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/ImplementMethodsTest.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,13 +15,12 @@
*/
package com.intellij.codeInsight;
-import com.intellij.codeInsight.daemon.quickFix.LightQuickFixAvailabilityTestCase;
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
/**
- * User: anna
- * Date: 10/7/11
+ * @author anna
*/
-public class ImplementMethodsTest extends LightQuickFixAvailabilityTestCase {
+public class ImplementMethodsTest extends LightQuickFixParameterizedTestCase {
public void test() throws Exception {
doAllTests();
}
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 4e8961dbe192..0b12b544bbfd 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
@@ -52,6 +52,7 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.statistics.StatisticsManager
import com.intellij.psi.statistics.impl.StatisticsManagerImpl
+import com.intellij.testFramework.EditorTestUtil
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.annotations.NotNull
@@ -1141,6 +1142,56 @@ class Foo {{
}}'''
}
+ public void testMulticaret() {
+ doTestMulticaret """
+class Foo {{
+ <selection>t<caret></selection>x;
+ <selection>t<caret></selection>x;
+}}""", '\n', '''
+class Foo {{
+ toString()<caret>x;
+ toString()<caret>x;
+}}'''
+ }
+
+ public void testMulticaretTab() {
+ doTestMulticaret """
+class Foo {{
+ <selection>t<caret></selection>x;
+ <selection>t<caret></selection>x;
+}}""", '\t', '''
+class Foo {{
+ toString()<caret>;
+ toString()<caret>;
+}}'''
+ }
+
+ public void testMulticaretBackspace() {
+ doTestMulticaret """
+class Foo {{
+ <selection>t<caret></selection>;
+ <selection>t<caret></selection>;
+}}""", '\b\t', '''
+class Foo {{
+ toString()<caret>;
+ toString()<caret>;
+}}'''
+ }
+
+ private doTestMulticaret(final String textBefore, final String toType, final String textAfter) {
+ EditorTestUtil.enableMultipleCarets()
+ try {
+ myFixture.configureByText "a.java", textBefore
+ type 'toStr'
+ assert lookup
+ type toType
+ myFixture.checkResult textAfter
+ }
+ finally {
+ EditorTestUtil.disableMultipleCarets()
+ }
+ }
+
private doTestBlockSelection(final String textBefore, final String toType, final String textAfter) {
myFixture.configureByText "a.java", textBefore
edt {
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 f07a9635da0c..35b71f8cc33b 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
@@ -1403,6 +1403,33 @@ class Foo {{
}
}
+ public void testPrimitiveSquareBracketWhenMultipleCaretsAreEnabled() {
+ EditorTestUtil.enableMultipleCarets()
+ try {
+ configureByFile("PrimitiveSquareBracket.java");
+ type('[');
+ checkResultByFile("PrimitiveSquareBracket_after.java");
+ }
+ finally {
+ EditorTestUtil.disableMultipleCarets()
+ }
+ }
+
+ public void testMulticaretTyping() {
+ EditorTestUtil.enableMultipleCarets()
+ try {
+ configure()
+ assert lookup
+ type('p')
+ assert lookup
+ type('\n')
+ checkResult()
+ }
+ finally {
+ EditorTestUtil.disableMultipleCarets()
+ }
+ }
+
public void "test complete lowercase class name"() {
myFixture.addClass("package foo; public class myClass {}")
myFixture.configureByText "a.java", """
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java
index 1868d2196d7c..964566fcf5ff 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java
@@ -39,6 +39,8 @@ public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testInapplicable() { doTest(false); }
public void testDuplicateAttribute() { doTest(false); }
public void testDuplicateTarget() { doTest(false); }
+ public void testPingPongAnnotationTypesDependencies() { doTest(false);}
+ public void testClashMethods() { doTest(false);}
public void testInvalidPackageAnnotationTarget() { doTest(BASE_PATH + "/" + getTestName(true) + "/package-info.java", false, false); }
public void testPackageAnnotationNotInPackageInfo() { doTest(BASE_PATH + "/" + getTestName(true) + "/notPackageInfo.java", false, false); }
@@ -46,9 +48,6 @@ public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testTypeAnnotations() { doTest8(false); }
public void testRepeatable() { doTest8(false); }
- public void testPingPongAnnotationTypesDependencies() { doTest(false);}
- public void testClashMethods() { doTest(false);}
-
private void doTest(boolean checkWarnings) {
setLanguageLevel(LanguageLevel.JDK_1_7);
doTest(BASE_PATH + "/" + getTestName(true) + ".java", checkWarnings, false);
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java
index b50052b71750..80448f9d3a96 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java
@@ -368,7 +368,7 @@ public class ImportHelperTest extends DaemonAnalyzerTestCase {
public void testAutoImportOfGenericReference() throws Throwable {
- @NonNls final String text = "class S {{ new ArrayList<caret><> }}";
+ @NonNls final String text = "class S {{ new ArrayList<caret><String> }}";
configureByText(StdFileTypes.JAVA, text);
boolean old = CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY;
CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY = true;
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalTypeWildcardParameterizationTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalTypeWildcardParameterizationTest.java
new file mode 100644
index 000000000000..599ae74cd00d
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/FunctionalTypeWildcardParameterizationTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.lambda;
+
+import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.testFramework.IdeaTestUtil;
+import org.jetbrains.annotations.NonNls;
+
+public class FunctionalTypeWildcardParameterizationTest extends LightDaemonAnalyzerTestCase {
+ @NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization";
+
+ public void testNonWildcardParametrization() throws Exception {
+ doTest();
+ }
+
+ public void testLambdaFormalParamTypesParametrization() throws Exception {
+ doTest();
+ }
+
+ public void testPrimitiveParameterTypes() throws Exception {
+ doTest();
+ }
+
+ private void doTest() {
+ IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable());
+ doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
+ }
+
+ @Override
+ protected Sdk getProjectJDK() {
+ return IdeaTestUtil.getMockJdk18();
+ }
+}
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 1119a0d6d4df..8af0821571d6 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
@@ -28,7 +28,7 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
doTest();
}
- public void _testNestedCallsSameMethod() throws Exception {
+ public void testNestedCallsSameMethod() throws Exception {
doTest();
}
@@ -160,6 +160,14 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
doTest();
}
+ public void testLiftedCaptureToOuterCall() throws Exception {
+ doTest();
+ }
+
+ public void testSiteSubstitutionForReturnConstraint() 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 89ddef20df0e..826193c90f90 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
@@ -138,6 +138,14 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
+ public void testDiamondInLambdaReturn() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA118965() 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 e944269c098b..83f0dfac5c1e 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
@@ -173,6 +173,14 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
+ public void testReturnTypeCheckForRawReceiver() throws Exception {
+ doTest();
+ }
+
+ public void testStaticNonStaticReferenceTypeAmbiguity() throws Exception {
+ doTest();
+ }
+
private void doTest() {
doTest(false);
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/navigation/JavaGotoSuperTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/navigation/JavaGotoSuperTest.java
new file mode 100644
index 000000000000..313720456ae5
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/navigation/JavaGotoSuperTest.java
@@ -0,0 +1,52 @@
+package com.intellij.codeInsight.navigation;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.codeInsight.CodeInsightActionHandler;
+import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
+import com.intellij.codeInsight.daemon.LineMarkerInfo;
+import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
+import com.intellij.lang.CodeInsightActions;
+import com.intellij.lang.java.JavaLanguage;
+import com.intellij.openapi.editor.Document;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+public class JavaGotoSuperTest extends LightDaemonAnalyzerTestCase {
+ @NotNull
+ @Override
+ protected String getTestDataPath() {
+ return JavaTestUtil.getJavaTestDataPath();
+ }
+
+ protected String getBasePath() {
+ return "/codeInsight/gotosuper/";
+ }
+
+ public void testLambda() throws Throwable {
+ doTest();
+ }
+
+ public void testLambdaMarker() throws Exception {
+ configureByFile(getBasePath() + getTestName(false) + ".java");
+ int offset = myEditor.getCaretModel().getOffset();
+
+ doHighlighting();
+ Document document = getEditor().getDocument();
+ List<LineMarkerInfo> markers = DaemonCodeAnalyzerImpl.getLineMarkers(document, getProject());
+ for (LineMarkerInfo info : markers) {
+ if (info.endOffset >= offset && info.startOffset <= offset) {
+ assertEquals("<html><body>Overrides method in 'I'</body></html>", info.getLineMarkerTooltip());
+ return;
+ }
+ }
+ fail("Gutter expected");
+ }
+
+ private void doTest() throws Throwable {
+ configureByFile(getBasePath() + getTestName(false) + ".java");
+ final CodeInsightActionHandler handler = CodeInsightActions.GOTO_SUPER.forLanguage(JavaLanguage.INSTANCE);
+ handler.invoke(getProject(), getEditor(), getFile());
+ checkResultByFile(getBasePath() + getTestName(false) + ".after.java");
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy
index f186f9e8f5c8..6373bc3ce307 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy
@@ -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,15 +15,22 @@
*/
package com.intellij.codeInsight.psi
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiFile
+import com.intellij.pom.java.LanguageLevel
+import com.intellij.psi.*
+import com.intellij.psi.impl.source.PsiImmediateClassType
import com.intellij.testFramework.LightIdeaTestCase
-@SuppressWarnings(["GrUnresolvedAccess", "GroovyAssignabilityCheck"])
+@SuppressWarnings("GroovyAssignabilityCheck")
class AnnotatedTypeTest extends LightIdeaTestCase {
+ private PsiFile context
+ private PsiElementFactory factory
+
+ public void setUp() throws Exception {
+ super.setUp()
+ factory = javaFacade.elementFactory
+ context = createFile("typeCompositionTest.java", """
+package pkg;
- public void testTypeComposition() {
- PsiFile context = createFile("typeCompositionTest.java", """
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
@@ -33,31 +40,55 @@ import static java.lang.annotation.ElementType.*;
class E1 extends Exception { }
class E2 extends Exception { }
""")
- PsiElement psi
+ }
+
+ public void testPrimitiveArrayType() {
+ doTest("@A @TA(1) int @TA(2) [] a", "@pkg.TA(1) int @pkg.TA(2) []", "int[]")
+ }
- psi = javaFacade.elementFactory.createStatementFromText("@A @TA(1) int @TA(2) [] a", context)
- assertEquals("@TA(1) int @TA(2) []", psi.declaredElements[0].type.presentableText)
+ public void testEllipsisType() {
+ def psi = factory.createParameterFromText("@TA int @TA ... p", context)
+ assertTypeText(psi.type, "@pkg.TA int @pkg.TA ...", "int...")
+ }
- psi = javaFacade.elementFactory.createStatementFromText("try { } catch (@A @TA(1) E1 | @TA(2) E2 e) { }", context)
- assertEquals("@TA(1) E1 | @TA(2) E2", psi.catchBlockParameters[0].type.presentableText)
+ public void testClassReferenceType() {
+ doTest("@A @TA(1) String s", "java.lang.@pkg.TA(1) String", "java.lang.String")
+ doTest("@A java.lang.@TA(1) String s", "java.lang.@pkg.TA(1) String", "java.lang.String")
+ }
- psi = javaFacade.elementFactory.createStatementFromText("@A @TA(1) String @TA(2) [] f @TA(3) []", context)
- assertEquals("@TA(1) String @TA(2) [] @TA(3) []", psi.declaredElements[0].type.presentableText)
+ public void testCStyleArrayType() {
+ doTest("@A @TA(1) String @TA(2) [] f @TA(3) []", "java.lang.@pkg.TA(1) String @pkg.TA(2) [] @pkg.TA(3) []", "java.lang.String[][]")
+ }
- psi = javaFacade.elementFactory.createStatementFromText("Class<@TA(1) ?> c", context)
- assertEquals("Class<@TA(1) ?>", psi.declaredElements[0].type.presentableText)
+ public void testWildcardType() {
+ doTest("Class<@TA(1) ?> c", "java.lang.Class<@pkg.TA(1) ?>", "java.lang.Class<?>")
+ }
- psi = javaFacade.elementFactory.createStatementFromText("Class<@TA String> cs = new Class<>()", context)
- assertEquals("Class<@TA String>", psi.declaredElements[0].initializer.type.presentableText)
+ public void testDisjunctionType() {
+ def psi = factory.createStatementFromText("try { } catch (@A @TA(1) E1 | @TA(2) E2 e) { }", context)
+ assertTypeText(psi.catchBlockParameters[0].type, "pkg.@pkg.TA(1) E1 | pkg.@pkg.TA(2) E2", "pkg.E1 | pkg.E2")
+ }
- psi = javaFacade.elementFactory.createStatementFromText("@A @TA(1) String s", context)
- assertEquals("@TA(1) String", psi.declaredElements[0].type.presentableText)
+ public void testDiamondType() {
+ def psi = factory.createStatementFromText("Class<@TA String> cs = new Class<>()", context)
+ assertTypeText(psi.declaredElements[0].initializer.type, "java.lang.Class<java.lang.@pkg.TA String>", "java.lang.Class<java.lang.String>")
+ }
- psi = javaFacade.elementFactory.createStatementFromText("@A java.lang.@TA(1) String s", context)
- assertEquals("@TA(1) String", psi.declaredElements[0].type.presentableText)
+ public void testImmediateClassType() {
+ def aClass = javaFacade.findClass(CommonClassNames.JAVA_LANG_OBJECT)
+ def statement = factory.createStatementFromText("@TA int x", context)
+ def annotations = statement.declaredElements[0].modifierList.annotations
+ def type = new PsiImmediateClassType(aClass, PsiSubstitutor.EMPTY, LanguageLevel.JDK_1_8, annotations)
+ assertTypeText(type, "java.lang.@pkg.TA Object", CommonClassNames.JAVA_LANG_OBJECT)
+ }
- psi = javaFacade.elementFactory.createStatementFromText("Collection<? extends> s", context)
- assertEquals("Collection<?>", psi.declaredElements[0].type.presentableText)
+ private void doTest(String text, String annotated, String canonical) {
+ def psi = factory.createStatementFromText(text, context)
+ assertTypeText(psi.declaredElements[0].type, annotated, canonical)
}
+ private static void assertTypeText(PsiType type, String annotated, String canonical) {
+ assert type.getCanonicalText(true) == annotated
+ assert type.getCanonicalText(false) == canonical
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
index c2cef13e6ea8..bfd1de796f90 100644
--- a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
+++ b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
@@ -194,7 +194,7 @@ public class FindManagerTest extends DaemonAnalyzerTestCase {
PsiDirectory psiDirectory = FindInProjectUtil.getPsiDirectory(findModel, myProject);
List<UsageInfo> result = new ArrayList<UsageInfo>();
final CommonProcessors.CollectProcessor<UsageInfo> collector = new CommonProcessors.CollectProcessor<UsageInfo>(result);
- FindInProjectUtil.findUsages(findModel, psiDirectory, myProject, true, collector, new FindUsagesProcessPresentation(FindInProjectUtil.setupViewPresentation(true, findModel)));
+ FindInProjectUtil.findUsages(findModel, psiDirectory, myProject, collector, new FindUsagesProcessPresentation(FindInProjectUtil.setupViewPresentation(true, findModel)));
return result;
}
diff --git a/java/java-tests/testSrc/com/intellij/index/IndexTest.java b/java/java-tests/testSrc/com/intellij/index/IndexTest.java
index fba5b6e5265d..7770c5e4a1f9 100644
--- a/java/java-tests/testSrc/com/intellij/index/IndexTest.java
+++ b/java/java-tests/testSrc/com/intellij/index/IndexTest.java
@@ -34,6 +34,7 @@ import com.intellij.testFramework.SkipSlowTestLocally;
import com.intellij.util.indexing.MapIndexStorage;
import com.intellij.util.indexing.StorageException;
import com.intellij.util.io.*;
+import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
@@ -113,7 +114,7 @@ public class IndexTest extends IdeaTestCase {
private PersistentHashMap<Integer, Collection<String>> createMetaIndex(File metaIndexFile) throws IOException {
return new PersistentHashMap<Integer, Collection<String>>(metaIndexFile, new EnumeratorIntegerDescriptor(), new DataExternalizer<Collection<String>>() {
@Override
- public void save(DataOutput out, Collection<String> value) throws IOException {
+ public void save(@NotNull DataOutput out, Collection<String> value) throws IOException {
DataInputOutputUtil.writeINT(out, value.size());
for (String key : value) {
out.writeUTF(key);
@@ -121,7 +122,7 @@ public class IndexTest extends IdeaTestCase {
}
@Override
- public Collection<String> read(DataInput in) throws IOException {
+ public Collection<String> read(@NotNull DataInput in) throws IOException {
final int size = DataInputOutputUtil.readINT(in);
final List<String> list = new ArrayList<String>();
for (int idx = 0; idx < size; idx++) {
diff --git a/java/java-tests/testSrc/com/intellij/index/StringIndex.java b/java/java-tests/testSrc/com/intellij/index/StringIndex.java
index a12f58fbf137..7d2dd108ceac 100644
--- a/java/java-tests/testSrc/com/intellij/index/StringIndex.java
+++ b/java/java-tests/testSrc/com/intellij/index/StringIndex.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.index;
import com.intellij.openapi.util.Factory;
@@ -28,7 +43,7 @@ public class StringIndex {
myIndex.setInputIdToDataKeysIndex(factory);
}
- public List<String> getFilesByWord(String word) throws StorageException {
+ public List<String> getFilesByWord(@NotNull String word) throws StorageException {
return myIndex.getData(word).toValueList();
}
diff --git a/java/java-tests/testSrc/com/intellij/openapi/editor/impl/JavaFileEditorManagerTest.java b/java/java-tests/testSrc/com/intellij/openapi/editor/impl/JavaFileEditorManagerTest.java
new file mode 100644
index 000000000000..2a985b873ee3
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/openapi/editor/impl/JavaFileEditorManagerTest.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.intellij.openapi.editor.impl;
+
+import com.intellij.openapi.fileEditor.FileEditorManagerTestCase;
+import com.intellij.testFramework.PlatformTestUtil;
+import org.jdom.JDOMException;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public class JavaFileEditorManagerTest extends FileEditorManagerTestCase {
+
+ public void testAsyncOpening() throws JDOMException, ExecutionException, InterruptedException, IOException {
+ openFiles("<component name=\"FileEditorManager\">\n" +
+ " <leaf>\n" +
+ " <file leaf-file-name=\"Bar.java\" pinned=\"false\" current=\"true\" current-in-tab=\"true\">\n" +
+ " <entry file=\"file://$PROJECT_DIR$/src/Bar.java\">\n" +
+ " <provider selected=\"true\" editor-type-id=\"text-editor\">\n" +
+ " <state vertical-scroll-proportion=\"0.032882012\" vertical-offset=\"0\" max-vertical-offset=\"517\">\n" +
+ " <caret line=\"1\" column=\"26\" selection-start=\"45\" selection-end=\"45\" />\n" +
+ " <folding>\n" +
+ " <element signature=\"e#69#70#0\" expanded=\"true\" />\n" +
+ " </folding>\n" +
+ " </state>\n" +
+ " </provider>\n" +
+ " </entry>\n" +
+ " </file>\n" +
+ " </leaf>\n" +
+ " </component>");
+ }
+
+ @Override
+ protected String getTestDataPath() {
+ return PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/java/java-tests/testData/fileEditorManager";
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java
index 58c02ef225b3..ab057c436baa 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/AbstractJavaFormatterTest.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.
@@ -42,6 +42,7 @@ import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.EnumMap;
+import java.util.List;
import java.util.Map;
/**
@@ -51,13 +52,20 @@ import java.util.Map;
* @since Apr 27, 2010 6:26:29 PM
*/
public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase {
-
@NotNull
- public static String shiftIndentInside(@NotNull String initial, final int i, boolean shiftEmptyLines) throws IOException {
+ public static String shiftIndentInside(@NotNull String initial, final int i, boolean shiftEmptyLines) {
StringBuilder result = new StringBuilder(initial.length());
- LineReader reader = new LineReader(new ByteArrayInputStream(initial.getBytes()));
+ List<byte[]> lines;
+ try {
+ LineReader reader = new LineReader(new ByteArrayInputStream(initial.getBytes("UTF-8")));
+ lines = reader.readLines();
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
boolean first = true;
- for (byte[] line : reader.readLines()) {
+ for (byte[] line : lines) {
try {
if (!first) result.append('\n');
if (line.length > 0 || shiftEmptyLines) {
@@ -75,7 +83,6 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase {
protected enum Action {REFORMAT, INDENT}
-
public static JavaCodeStyleSettings getJavaSettings() {
return getSettings().getRootSettings().getCustomSettings(JavaCodeStyleSettings.class);
}
@@ -116,20 +123,15 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase {
return rootSettings.getCommonSettings(JavaLanguage.INSTANCE);
}
- //public static JavaCodeStyleSettings getJavaSettings() {
- // CodeStyleSettings rootSettings = CodeStyleSettingsManager.getSettings(getProject());
- // return rootSettings.getCustomSettings(JavaCodeStyleSettings.class);
- //}
- //
public static CommonCodeStyleSettings.IndentOptions getIndentOptions() {
return getSettings().getRootSettings().getIndentOptions(StdFileTypes.JAVA);
}
- public void doTest() throws Exception {
+ public void doTest() {
doTest(getTestName(false) + ".java", getTestName(false) + "_after.java");
}
- public void doTest(@NonNls String fileNameBefore, @NonNls String fileNameAfter) throws Exception {
+ public void doTest(@NonNls String fileNameBefore, @NonNls String fileNameAfter) {
doTextTest(Action.REFORMAT, loadFile(fileNameBefore), loadFile(fileNameAfter));
}
@@ -137,7 +139,7 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase {
doTextTest(Action.REFORMAT, text, textAfter);
}
- public void doTextTest(@NotNull final Action action, @NotNull final String text, @NotNull String textAfter) throws IncorrectOperationException {
+ public void doTextTest(@NotNull final Action action, @NotNull String text, @NotNull String textAfter) throws IncorrectOperationException {
final PsiFile file = createFile("A.java", text);
final PsiDocumentManager manager = PsiDocumentManager.getInstance(getProject());
final Document document = manager.getDocument(file);
@@ -204,7 +206,7 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase {
return document.getText();
}
- public void doMethodTest(@NonNls final String before, @NonNls final String after) throws Exception {
+ public void doMethodTest(@NonNls final String before, @NonNls final String after) {
doTextTest(
Action.REFORMAT,
"class Foo{\n" + " void foo() {\n" + before + '\n' + " }\n" + "}",
@@ -212,7 +214,7 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase {
);
}
- public void doClassTest(@NonNls final String before, @NonNls final String after) throws Exception {
+ public void doClassTest(@NonNls final String before, @NonNls final String after) {
doTextTest(
Action.REFORMAT,
"class Foo{\n" + before + '\n' + "}",
@@ -220,10 +222,14 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase {
);
}
- private static String loadFile(String name) throws Exception {
+ private static String loadFile(String name) {
String fullName = BASE_PATH + File.separatorChar + name;
- String text = FileUtil.loadFile(new File(fullName));
- text = StringUtil.convertLineSeparators(text);
- return text;
+ try {
+ String text = FileUtil.loadFile(new File(fullName));
+ return StringUtil.convertLineSeparators(text);
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterNewLineTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterNewLineTest.java
index 038b1d01f0e1..a7473f61e5a4 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterNewLineTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterNewLineTest.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.
@@ -28,7 +28,7 @@ import com.intellij.util.IncorrectOperationException;
*/
public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest {
- public void testAutomaticElseWrapping() throws Exception {
+ public void testAutomaticElseWrapping() {
getSettings().ELSE_ON_NEW_LINE = true;
doMethodTest(
@@ -43,7 +43,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest {
);
}
- public void testAutomaticElseUnwrapping() throws Exception {
+ public void testAutomaticElseUnwrapping() {
getSettings().ELSE_ON_NEW_LINE = false;
getSettings().KEEP_LINE_BREAKS = true;
@@ -60,7 +60,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest {
);
}
- public void testAutomaticCatchWrapping() throws Exception {
+ public void testAutomaticCatchWrapping() {
getSettings().CATCH_ON_NEW_LINE = true;
doMethodTest(
@@ -75,7 +75,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest {
);
}
- public void testAutomaticCatchUnwrapping() throws Exception {
+ public void testAutomaticCatchUnwrapping() {
getSettings().CATCH_ON_NEW_LINE = false;
getSettings().KEEP_LINE_BREAKS = true;
@@ -92,7 +92,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest {
);
}
- public void testAutomaticFinallyWrapping() throws Exception {
+ public void testAutomaticFinallyWrapping() {
getSettings().FINALLY_ON_NEW_LINE = true;
doMethodTest(
@@ -107,7 +107,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest {
);
}
- public void testAutomaticFinallyUnwrapping() throws Exception {
+ public void testAutomaticFinallyUnwrapping() {
getSettings().FINALLY_ON_NEW_LINE = false;
getSettings().KEEP_LINE_BREAKS = true;
@@ -124,7 +124,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest {
);
}
- public void testAutomaticCatchFinallyUnwrapping() throws Exception {
+ public void testAutomaticCatchFinallyUnwrapping() {
// Inspired by IDEA-47809
getSettings().CATCH_ON_NEW_LINE = false;
getSettings().FINALLY_ON_NEW_LINE = false;
@@ -144,8 +144,8 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest {
"}"
);
}
-
- public void testClassInitializationBlockBracesPlacement() throws Exception {
+
+ public void testClassInitializationBlockBracesPlacement() {
// Inspired by IDEA-54191
getSettings().getRootSettings().getIndentOptions(StdFileTypes.JAVA).INDENT_SIZE = 4;
getSettings().KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = false;
@@ -161,7 +161,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest {
);
}
- public void testBlockOfMethodWithAnnotatedParameter() throws Exception {
+ public void testBlockOfMethodWithAnnotatedParameter() {
// Inspired by IDEA-17870
doClassTest("public Test(@Qualifier(\"blah\") AType blah){}", "public Test(@Qualifier(\"blah\") AType blah) {\n" + "}");
}
@@ -193,7 +193,7 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest {
);
}
- public void testSimpleAnnotatedMethodAndBraceOnNextLineStyle() throws Exception {
+ public void testSimpleAnnotatedMethodAndBraceOnNextLineStyle() {
// Inspired by IDEA-53542
getSettings().METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE;
getSettings().KEEP_SIMPLE_METHODS_IN_ONE_LINE = true;
diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/ShortenClassReferencesTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/ShortenClassReferencesTest.java
index e21c18022e1e..4554f93fb20d 100644
--- a/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/ShortenClassReferencesTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/ShortenClassReferencesTest.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.
@@ -61,6 +61,7 @@ public class ShortenClassReferencesTest extends LightCodeInsightFixtureTestCase
public void testSCR37254() { doTest(); }
public void testTypeAnnotatedRef() {
+ myFixture.configureByFile("pkg/TA.java");
doTest();
for (PsiParameter parameter : PsiTreeUtil.findChildrenOfType(myFixture.getFile(), PsiParameter.class)) {
PsiTypeElement typeElement = parameter.getTypeElement();
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java
index 51905419d22c..4f6c44824ab6 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.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.
@@ -34,360 +34,388 @@ import java.util.HashSet;
* @author dsl
*/
public class ChangeSignatureTest extends LightRefactoringTestCase {
- public void testSimple() throws Exception {
+ private PsiElementFactory myFactory;
+
+ public void setUp() throws Exception {
+ super.setUp();
+ myFactory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
+ }
+
+ public void testSimple() {
doTest(null, null, null, new ParameterInfoImpl[0], new ThrownExceptionInfo[0], false);
}
- public void testParameterReorder() throws Exception {
+ public void testParameterReorder() {
doTest(null, new ParameterInfoImpl[]{new ParameterInfoImpl(1), new ParameterInfoImpl(0)}, false);
}
- public void testWarnAboutContract() throws Exception {
+ public void testWarnAboutContract() {
try {
doTest(null, new ParameterInfoImpl[]{new ParameterInfoImpl(1), new ParameterInfoImpl(0)}, false);
fail("Conflict expected");
}
- catch (BaseRefactoringProcessor.ConflictsInTestsException ignored) {
- }
+ catch (BaseRefactoringProcessor.ConflictsInTestsException ignored) { }
}
- public void testGenericTypes() throws Exception {
+ public void testGenericTypes() {
doTest(null, null, "T", new GenParams() {
@Override
public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException {
- final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
return new ParameterInfoImpl[]{
- new ParameterInfoImpl(-1, "x", factory.createTypeFromText("T", method.getParameterList()), "null"),
- new ParameterInfoImpl(-1, "y", factory.createTypeFromText("C<T>", method.getParameterList()), "null")
+ new ParameterInfoImpl(-1, "x", myFactory.createTypeFromText("T", method.getParameterList()), "null"),
+ new ParameterInfoImpl(-1, "y", myFactory.createTypeFromText("C<T>", method.getParameterList()), "null")
};
}
}, false);
}
- public void testGenericTypesInOldParameters() throws Exception {
+ public void testGenericTypesInOldParameters() {
doTest(null, null, null, new GenParams() {
@Override
public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException {
- final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
- return new ParameterInfoImpl[] {
- new ParameterInfoImpl(0, "t", factory.createTypeFromText("T", method), null)
+ return new ParameterInfoImpl[]{
+ new ParameterInfoImpl(0, "t", myFactory.createTypeFromText("T", method), null)
};
}
}, false);
}
- public void testTypeParametersInMethod() throws Exception {
+ public void testTypeParametersInMethod() {
doTest(null, null, null, new GenParams() {
- @Override
- public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException {
- final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
- return new ParameterInfoImpl[]{
- new ParameterInfoImpl(-1, "t", factory.createTypeFromText("T", method.getParameterList()), "null"),
- new ParameterInfoImpl(-1, "u", factory.createTypeFromText("U", method.getParameterList()), "null"),
- new ParameterInfoImpl(-1, "cu", factory.createTypeFromText("C<U>", method.getParameterList()), "null")
- };
- }
- }, false);
+ @Override
+ public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException {
+ return new ParameterInfoImpl[]{
+ new ParameterInfoImpl(-1, "t", myFactory.createTypeFromText("T", method.getParameterList()), "null"),
+ new ParameterInfoImpl(-1, "u", myFactory.createTypeFromText("U", method.getParameterList()), "null"),
+ new ParameterInfoImpl(-1, "cu", myFactory.createTypeFromText("C<U>", method.getParameterList()), "null")
+ };
+ }
+ }, false);
}
- public void testDefaultConstructor() throws Exception {
+ public void testDefaultConstructor() {
doTest(null,
- new ParameterInfoImpl[] {
- new ParameterInfoImpl(-1, "j", PsiType.INT, "27")
- }, false);
+ new ParameterInfoImpl[]{
+ new ParameterInfoImpl(-1, "j", PsiType.INT, "27")
+ }, false
+ );
}
- public void testGenerateDelegate() throws Exception {
+ public void testGenerateDelegate() {
doTest(null,
- new ParameterInfoImpl[] {
+ new ParameterInfoImpl[]{
new ParameterInfoImpl(-1, "i", PsiType.INT, "27")
- }, true);
+ }, true
+ );
}
- public void testGenerateDelegateForAbstract() throws Exception {
+ public void testGenerateDelegateForAbstract() {
doTest(null,
- new ParameterInfoImpl[] {
+ new ParameterInfoImpl[]{
new ParameterInfoImpl(-1, "i", PsiType.INT, "27")
- }, true);
+ }, true
+ );
}
- public void testGenerateDelegateWithReturn() throws Exception {
+ public void testGenerateDelegateWithReturn() {
doTest(null,
- new ParameterInfoImpl[] {
+ new ParameterInfoImpl[]{
new ParameterInfoImpl(-1, "i", PsiType.INT, "27")
- }, true);
+ }, true
+ );
}
- public void testGenerateDelegateWithParametersReordering() throws Exception {
+ public void testGenerateDelegateWithParametersReordering() {
doTest(null,
- new ParameterInfoImpl[] {
+ new ParameterInfoImpl[]{
new ParameterInfoImpl(1),
new ParameterInfoImpl(-1, "c", PsiType.CHAR, "'a'"),
new ParameterInfoImpl(0, "j", PsiType.INT)
- }, true);
+ }, true
+ );
}
- public void testGenerateDelegateConstructor() throws Exception {
+ public void testGenerateDelegateConstructor() {
doTest(null, new ParameterInfoImpl[0], true);
}
- public void testGenerateDelegateDefaultConstructor() throws Exception {
- doTest(null, new ParameterInfoImpl[] {
+ public void testGenerateDelegateDefaultConstructor() {
+ doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(-1, "i", PsiType.INT, "27")
}, true);
}
- public void testSCR40895() throws Exception {
- doTest(null, new ParameterInfoImpl[] {
+ public void testSCR40895() {
+ doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(0, "y", PsiType.INT),
new ParameterInfoImpl(1, "b", PsiType.BOOLEAN)
}, false);
}
- public void testJavadocGenericsLink() throws Exception {
- doTest(null, new ParameterInfoImpl[] {
- new ParameterInfoImpl(-1, "y", JavaPsiFacade.getElementFactory(getProject()).createTypeFromText("java.util.List<java.lang.String>", null)),
+ public void testJavadocGenericsLink() {
+ doTest(null, new ParameterInfoImpl[]{
+ new ParameterInfoImpl(-1, "y", myFactory.createTypeFromText("java.util.List<java.lang.String>", null)),
new ParameterInfoImpl(0, "a", PsiType.BOOLEAN)
}, false);
}
- public void testParamNameSameAsFieldName() throws Exception {
- doTest(null, new ParameterInfoImpl[] {
+ public void testParamNameSameAsFieldName() {
+ doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(0, "fieldName", PsiType.INT)
}, false);
}
- public void testParamNameNoConflict() throws Exception {
+ public void testParamNameNoConflict() {
doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(0),
new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN)
}, false);
}
- public void testParamJavadoc() throws Exception {
- doTest(null, new ParameterInfoImpl[] {
+ public void testParamJavadoc() {
+ doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(1, "z", PsiType.INT),
new ParameterInfoImpl(0, "y", PsiType.INT)
}, false);
}
- public void testParamJavadoc0() throws Exception {
- doTest(null, new ParameterInfoImpl[] {
+ public void testParamJavadoc0() {
+ doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(1, "z", PsiType.INT),
new ParameterInfoImpl(0, "y", PsiType.INT)
}, false);
}
- public void testParamJavadoc1() throws Exception {
+ public void testParamJavadoc1() {
doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(0, "z", PsiType.BOOLEAN)
}, false);
}
- public void testParamJavadoc2() throws Exception {
+ public void testParamJavadoc2() {
doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(-1, "z", PsiType.BOOLEAN),
new ParameterInfoImpl(0, "a", PsiType.BOOLEAN),
}, false);
}
- public void testJavadocNoNewLineInserted() throws Exception {
+ public void testJavadocNoNewLineInserted() {
doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(0, "newArgs", PsiType.DOUBLE),
}, false);
}
- public void testSuperCallFromOtherMethod() throws Exception {
- doTest(null, new ParameterInfoImpl[] {
+ public void testSuperCallFromOtherMethod() {
+ doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(-1, "nnn", PsiType.INT, "-222"),
}, false);
}
- public void testUseAnyVariable() throws Exception {
+ public void testUseAnyVariable() {
doTest(null, null, null, new GenParams() {
@Override
public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException {
- final PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
- return new ParameterInfoImpl[] {
- new ParameterInfoImpl(-1, "l", factory.createTypeFromText("List", method), "null", true)
+ return new ParameterInfoImpl[]{
+ new ParameterInfoImpl(-1, "l", myFactory.createTypeFromText("List", method), "null", true)
};
}
}, false);
}
- public void testUseThisAsAnyVariable() throws Exception {
+ public void testUseThisAsAnyVariable() {
doTest(null, null, null, new GenParams() {
@Override
public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException {
- final PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
- return new ParameterInfoImpl[] {
- new ParameterInfoImpl(-1, "l", factory.createTypeFromText("List", method), "null", true)
+ return new ParameterInfoImpl[]{
+ new ParameterInfoImpl(-1, "l", myFactory.createTypeFromText("List", method), "null", true)
};
}
}, false);
}
- public void testUseAnyVariableAndDefault() throws Exception {
+ public void testUseAnyVariableAndDefault() {
doTest(null, null, null, new GenParams() {
@Override
public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException {
- final PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
- return new ParameterInfoImpl[] {
- new ParameterInfoImpl(-1, "c", factory.createTypeFromText("C", method), "null", true)
+ return new ParameterInfoImpl[]{
+ new ParameterInfoImpl(-1, "c", myFactory.createTypeFromText("C", method), "null", true)
};
}
}, false);
}
- public void testRemoveVarargParameter() throws Exception {
+ public void testRemoveVarargParameter() {
doTest(null, null, null, new ParameterInfoImpl[]{new ParameterInfoImpl(0)}, new ThrownExceptionInfo[0], false);
}
- public void testEnumConstructor() throws Exception {
- doTest(null, new ParameterInfoImpl[] {
+ public void testEnumConstructor() {
+ doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(-1, "i", PsiType.INT, "10")
}, false);
}
- public void testVarargs1() throws Exception {
- doTest(null, new ParameterInfoImpl[] {
+ public void testVarargs1() {
+ doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN, "true"),
new ParameterInfoImpl(0)
}, false);
}
- public void testVarargs2() throws Exception {
- doTest(null, new ParameterInfoImpl[] {
+ public void testVarargs2() {
+ doTest(null, new ParameterInfoImpl[]{
new ParameterInfoImpl(1, "i", PsiType.INT),
new ParameterInfoImpl(0, "b", new PsiEllipsisType(PsiType.BOOLEAN))
}, false);
}
- public void testCovariantReturnType() throws Exception {
+ public void testCovariantReturnType() {
doTest(CommonClassNames.JAVA_LANG_RUNNABLE, new ParameterInfoImpl[0], false);
}
- public void testReorderExceptions() throws Exception {
+ public void testReorderExceptions() {
doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]),
- new SimpleExceptionsGen(new ThrownExceptionInfo[]{new JavaThrownExceptionInfo(1), new JavaThrownExceptionInfo(0)}),
- false);
+ new SimpleExceptionsGen(new ThrownExceptionInfo[]{new JavaThrownExceptionInfo(1), new JavaThrownExceptionInfo(0)}), false);
}
- public void testAlreadyHandled() throws Exception {
+ public void testAlreadyHandled() {
doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]),
new GenExceptions() {
@Override
public ThrownExceptionInfo[] genExceptions(PsiMethod method) {
- return new ThrownExceptionInfo[] {
- new JavaThrownExceptionInfo(-1, JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createTypeByFQClassName("java.lang.Exception", method.getResolveScope()))
+ return new ThrownExceptionInfo[]{
+ new JavaThrownExceptionInfo(-1, myFactory.createTypeByFQClassName("java.lang.Exception", method.getResolveScope()))
};
}
},
- false);
+ false
+ );
}
- public void testConstructorException() throws Exception {
+ public void testConstructorException() {
doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]),
new GenExceptions() {
@Override
public ThrownExceptionInfo[] genExceptions(PsiMethod method) {
- return new ThrownExceptionInfo[] {
- new JavaThrownExceptionInfo(-1, JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createTypeByFQClassName("java.io.IOException", method.getResolveScope()))
+ return new ThrownExceptionInfo[]{
+ new JavaThrownExceptionInfo(-1, myFactory.createTypeByFQClassName("java.io.IOException", method.getResolveScope()))
};
}
},
- false);
+ false
+ );
}
- public void testAddRuntimeException() throws Exception {
+ public void testAddRuntimeException() {
doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]),
new GenExceptions() {
@Override
public ThrownExceptionInfo[] genExceptions(PsiMethod method) {
- return new ThrownExceptionInfo[] {
- new JavaThrownExceptionInfo(-1, JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createTypeByFQClassName("java.lang.RuntimeException", method.getResolveScope()))
+ return new ThrownExceptionInfo[]{
+ new JavaThrownExceptionInfo(-1, myFactory.createTypeByFQClassName("java.lang.RuntimeException", method.getResolveScope()))
};
}
},
- false);
+ false
+ );
}
- public void testAddException() throws Exception {
+ public void testAddException() {
doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]),
new GenExceptions() {
@Override
public ThrownExceptionInfo[] genExceptions(PsiMethod method) {
- return new ThrownExceptionInfo[] {
- new JavaThrownExceptionInfo(-1, JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createTypeByFQClassName("java.lang.Exception", method.getResolveScope()))
+ return new ThrownExceptionInfo[]{
+ new JavaThrownExceptionInfo(-1, myFactory.createTypeByFQClassName("java.lang.Exception", method.getResolveScope()))
};
}
},
- false);
+ false
+ );
}
- public void testReorderWithVarargs() throws Exception { // IDEADEV-26977
- final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
- doTest(null, new ParameterInfoImpl[] {
- new ParameterInfoImpl(1),
- new ParameterInfoImpl(0, "s", factory.createTypeFromText("java.lang.String...", getFile()))
+ public void testReorderWithVarargs() { // IDEADEV-26977
+ doTest(null, new ParameterInfoImpl[]{
+ new ParameterInfoImpl(1),
+ new ParameterInfoImpl(0, "s", myFactory.createTypeFromText("java.lang.String...", getFile()))
}, false);
}
- public void testIntroduceParameterWithDefaultValueInHierarchy() throws Exception {
+ public void testIntroduceParameterWithDefaultValueInHierarchy() {
doTest(null, new ParameterInfoImpl[]{new ParameterInfoImpl(-1, "i", PsiType.INT, "0")}, false);
}
- public void testReorderMultilineMethodParameters() throws Exception {
+ public void testReorderMultilineMethodParameters() {
// Inspired by IDEA-54902
- doTest(null, new ParameterInfoImpl[] {new ParameterInfoImpl(1), new ParameterInfoImpl(0)}, false);
+ doTest(null, new ParameterInfoImpl[]{new ParameterInfoImpl(1), new ParameterInfoImpl(0)}, false);
}
- public void testRemoveFirstParameter() throws Exception {
+ public void testRemoveFirstParameter() {
doTest(null, new ParameterInfoImpl[]{new ParameterInfoImpl(1)}, false);
}
- public void testReplaceVarargWithArray() throws Exception {
+ public void testReplaceVarargWithArray() {
doTest(null, null, null, new GenParams() {
@Override
public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException {
- final PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
- return new ParameterInfoImpl[] {
- new ParameterInfoImpl(1, "l", factory.createTypeFromText("List<T>[]", method.getParameterList()), "null", false),
- new ParameterInfoImpl(0, "s", factory.createTypeFromText("String", method.getParameterList()))
+ return new ParameterInfoImpl[]{
+ new ParameterInfoImpl(1, "l", myFactory.createTypeFromText("List<T>[]", method.getParameterList()), "null", false),
+ new ParameterInfoImpl(0, "s", myFactory.createTypeFromText("String", method.getParameterList()))
};
}
}, false);
}
- public void testMethodParametersAlignmentAfterMethodNameChange() throws Exception {
+ public void testMethodParametersAlignmentAfterMethodNameChange() {
getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS = true;
getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
doTest(null, "test123asd", null, new SimpleParameterGen(), new SimpleExceptionsGen(), false);
}
- public void testMethodParametersAlignmentAfterMethodVisibilityChange() throws Exception {
+ public void testMethodParametersAlignmentAfterMethodVisibilityChange() {
getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS = true;
getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
doTest(PsiModifier.PROTECTED, null, null, new SimpleParameterGen(), new SimpleExceptionsGen(), false);
}
- public void testMethodParametersAlignmentAfterMethodReturnTypeChange() throws Exception {
+ public void testMethodParametersAlignmentAfterMethodReturnTypeChange() {
getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS = true;
getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
doTest(null, null, "Exception", new SimpleParameterGen(), new SimpleExceptionsGen(), false);
}
- public void testVisibilityOfOverriddenMethod() throws Exception {
+ public void testVisibilityOfOverriddenMethod() {
doTest(PsiModifier.PACKAGE_LOCAL, "foo", "void", new ParameterInfoImpl[0], new ThrownExceptionInfo[0], false);
}
- public void testRemoveExceptions() throws Exception {
+ public void testRemoveExceptions() {
doTest(null, null, "void", new SimpleParameterGen(), new SimpleExceptionsGen(), false);
}
- private void doTest(@Nullable String newReturnType,
- ParameterInfoImpl[] parameterInfos,
- final boolean generateDelegate) throws Exception {
+ public void testPropagateParameter() {
+ String basePath = "/refactoring/changeSignature/" + getTestName(false);
+ configureByFile(basePath + ".java");
+ final PsiElement targetElement = TargetElementUtilBase.findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
+ assertTrue("<caret> is not on method name", targetElement instanceof PsiMethod);
+ PsiMethod method = (PsiMethod)targetElement;
+ final PsiClass containingClass = method.getContainingClass();
+ assertTrue(containingClass != null);
+ final PsiMethod[] callers = containingClass.findMethodsByName("caller", false);
+ assertTrue(callers.length > 0);
+ final PsiMethod caller = callers[0];
+ final HashSet<PsiMethod> propagateParametersMethods = new HashSet<PsiMethod>();
+ propagateParametersMethods.add(caller);
+ final PsiParameter[] parameters = method.getParameterList().getParameters();
+ new ChangeSignatureProcessor(getProject(), method, false, null, method.getName(),
+ CanonicalTypes.createTypeWrapper(PsiType.VOID), new ParameterInfoImpl[]{
+ new ParameterInfoImpl(0, parameters[0].getName(), parameters[0].getType()),
+ new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN)}, null, propagateParametersMethods, null
+ ).run();
+ checkResultByFile(basePath + "_after.java");
+ }
+
+ /* workers */
+
+ private void doTest(@Nullable String newReturnType, ParameterInfoImpl[] parameterInfos, boolean generateDelegate) {
doTest(null, null, newReturnType, parameterInfos, new ThrownExceptionInfo[0], generateDelegate);
}
@@ -396,14 +424,15 @@ public class ChangeSignatureTest extends LightRefactoringTestCase {
@Nullable String newReturnType,
ParameterInfoImpl[] parameterInfo,
ThrownExceptionInfo[] exceptionInfo,
- final boolean generateDelegate) throws Exception {
+ boolean generateDelegate) {
doTest(newVisibility, newName, newReturnType, new SimpleParameterGen(parameterInfo), new SimpleExceptionsGen(exceptionInfo), generateDelegate);
}
private void doTest(@PsiModifier.ModifierConstant @Nullable String newVisibility,
@Nullable String newName,
@Nullable @NonNls String newReturnType,
- GenParams gen, final boolean generateDelegate) throws Exception {
+ GenParams gen,
+ boolean generateDelegate) {
doTest(newVisibility, newName, newReturnType, gen, new SimpleExceptionsGen(), generateDelegate);
}
@@ -412,45 +441,17 @@ public class ChangeSignatureTest extends LightRefactoringTestCase {
@Nullable String newReturnType,
GenParams genParams,
GenExceptions genExceptions,
- final boolean generateDelegate) throws Exception {
+ boolean generateDelegate) {
String basePath = "/refactoring/changeSignature/" + getTestName(false);
- @NonNls final String filePath = basePath + ".java";
- configureByFile(filePath);
- final PsiElement targetElement = TargetElementUtilBase.findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
+ configureByFile(basePath + ".java");
+ PsiElement targetElement = TargetElementUtilBase.findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
assertTrue("<caret> is not on method name", targetElement instanceof PsiMethod);
- PsiMethod method = (PsiMethod) targetElement;
- final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
- PsiType newType = newReturnType != null ? factory.createTypeFromText(newReturnType, method) : method.getReturnType();
+ PsiMethod method = (PsiMethod)targetElement;
+ PsiType newType = newReturnType != null ? myFactory.createTypeFromText(newReturnType, method) : method.getReturnType();
new ChangeSignatureProcessor(getProject(), method, generateDelegate, newVisibility,
newName != null ? newName : method.getName(),
newType, genParams.genParams(method), genExceptions.genExceptions(method)).run();
- @NonNls String after = basePath + "_after.java";
- checkResultByFile(after);
- }
-
- public void testPropagateParameter() throws Exception {
- String basePath = "/refactoring/changeSignature/" + getTestName(false);
- @NonNls final String filePath = basePath + ".java";
- configureByFile(filePath);
- final PsiElement targetElement = TargetElementUtilBase.findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
- assertTrue("<caret> is not on method name", targetElement instanceof PsiMethod);
- PsiMethod method = (PsiMethod) targetElement;
- final PsiClass containingClass = method.getContainingClass();
- assertTrue(containingClass != null);
- final PsiMethod[] callers = containingClass.findMethodsByName("caller", false);
- assertTrue(callers.length > 0);
- final PsiMethod caller = callers[0];
- final HashSet<PsiMethod> propagateParametersMethods = new HashSet<PsiMethod>();
- propagateParametersMethods.add(caller);
- final PsiParameter[] parameters = method.getParameterList().getParameters();
- new ChangeSignatureProcessor(getProject(), method, false, null,
- method.getName(),
- CanonicalTypes.createTypeWrapper(PsiType.VOID), new ParameterInfoImpl[]{
- new ParameterInfoImpl(0, parameters[0].getName(), parameters[0].getType()),
- new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN)}, null,
- propagateParametersMethods, null).run();
- @NonNls String after = basePath + "_after.java";
- checkResultByFile(after);
+ checkResultByFile(basePath + "_after.java");
}
private interface GenParams {
@@ -460,8 +461,7 @@ public class ChangeSignatureTest extends LightRefactoringTestCase {
private static class SimpleParameterGen implements GenParams {
private ParameterInfoImpl[] myInfos;
- private SimpleParameterGen() {
- }
+ private SimpleParameterGen() { }
private SimpleParameterGen(ParameterInfoImpl[] infos) {
myInfos = infos;
diff --git a/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java b/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java
index 2749c340c695..7521d3bd7c13 100644
--- a/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java
+++ b/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java
@@ -21,16 +21,22 @@ import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.util.xmlb.annotations.Attribute;
+import com.intellij.util.xmlb.annotations.Tag;
+import com.intellij.util.xmlb.annotations.Transient;
import org.jdom.Element;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+@Tag("class-filter")
public class ClassFilter implements JDOMExternalizable, Cloneable{
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.classFilter.ClassFilter");
public static final ClassFilter[] EMPTY_ARRAY = new ClassFilter[0];
+ @Attribute("pattern")
public String PATTERN = "";
+ @Attribute("enabled")
public boolean ENABLED = true;
private Matcher myMatcher; // to speedup matching
@@ -42,9 +48,12 @@ public class ClassFilter implements JDOMExternalizable, Cloneable{
ENABLED = true;
}
+ @Transient
public String getPattern() {
return PATTERN;
}
+
+ @Transient
public boolean isEnabled() {
return ENABLED;
}
diff --git a/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java b/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java
index 26e0eb52d34a..d7dfea857ba9 100644
--- a/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java
+++ b/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java
@@ -311,26 +311,26 @@ public abstract class ExecutionWithDebuggerToolsTestCase extends ExecutionTestCa
String suspendPolicy = readValue(comment, "suspendPolicy");
if (suspendPolicy != null) {
- breakpoint.SUSPEND = !DebuggerSettings.SUSPEND_NONE.equals(suspendPolicy);
- breakpoint.SUSPEND_POLICY = suspendPolicy;
+ //breakpoint.setSuspend(!DebuggerSettings.SUSPEND_NONE.equals(suspendPolicy));
+ breakpoint.setSuspendPolicy(suspendPolicy);
println("SUSPEND_POLICY = " + suspendPolicy, ProcessOutputTypes.SYSTEM);
}
String condition = readValue(comment, "Condition");
if (condition != null) {
- breakpoint.CONDITION_ENABLED = true;
+ //breakpoint.CONDITION_ENABLED = true;
breakpoint.setCondition(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, condition));
println("Condition = " + condition, ProcessOutputTypes.SYSTEM);
}
String passCount = readValue(comment, "Pass count");
if (passCount != null) {
- breakpoint.COUNT_FILTER_ENABLED = true;
- breakpoint.COUNT_FILTER = Integer.parseInt(passCount);
+ breakpoint.setCountFilterEnabled(true);
+ breakpoint.setCountFilter(Integer.parseInt(passCount));
println("Pass count = " + passCount, ProcessOutputTypes.SYSTEM);
}
String classFilters = readValue(comment, "Class filters");
if (classFilters != null) {
- breakpoint.CLASS_FILTERS_ENABLED = true;
+ breakpoint.setClassFiltersEnabled(true);
StringTokenizer tokenizer = new StringTokenizer(classFilters, " ,");
ArrayList<ClassFilter> lst = new ArrayList<ClassFilter>();
diff --git a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java
index f6f140049f21..5930288f2c2c 100644
--- a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java
+++ b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.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.
@@ -39,6 +39,7 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
public abstract class ModuleTestCase extends IdeaTestCase {
protected final Collection<Module> myModulesToDispose = new ArrayList<Module>();
@@ -100,6 +101,7 @@ public abstract class ModuleTestCase extends IdeaTestCase {
@Override
public Module compute() {
try {
+ LocalFileSystem.getInstance().refreshIoFiles(Collections.singletonList(moduleFile));
return ModuleManager.getInstance(myProject).loadModule(moduleFile.getAbsolutePath());
}
catch (Exception e) {
@@ -162,6 +164,7 @@ public abstract class ModuleTestCase extends IdeaTestCase {
FileUtil.copyDir(dirInTestDataFile, moduleDir);
final Module module = createModule(moduleDir + "/" + newModuleFileName, moduleType);
final VirtualFile root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(moduleDir);
+ assertNotNull(root);
new WriteCommandAction.Simple(module.getProject()) {
@Override
protected void run() throws Throwable {
diff --git a/jps/jps-builders/jps-builders.iml b/jps/jps-builders/jps-builders.iml
index fea80a020e80..9dd56d591d6e 100644
--- a/jps/jps-builders/jps-builders.iml
+++ b/jps/jps-builders/jps-builders.iml
@@ -36,6 +36,7 @@
<orderEntry type="module" module-name="jps-model-serialization" />
<orderEntry type="module" module-name="jps-model-impl" />
<orderEntry type="library" scope="TEST" name="Groovy" level="project" />
+ <orderEntry type="module" module-name="jps-serialization-tests" scope="TEST" />
</component>
</module>
diff --git a/jps/jps-builders/src/META-INF/services/org.jetbrains.jps.builders.java.JavaCompilingTool b/jps/jps-builders/src/META-INF/services/org.jetbrains.jps.builders.java.JavaCompilingTool
new file mode 100644
index 000000000000..f26b04843daf
--- /dev/null
+++ b/jps/jps-builders/src/META-INF/services/org.jetbrains.jps.builders.java.JavaCompilingTool
@@ -0,0 +1,2 @@
+org.jetbrains.jps.builders.impl.java.JavacCompilerTool
+org.jetbrains.jps.builders.impl.java.EclipseCompilerTool \ No newline at end of file
diff --git a/jps/jps-builders/src/org/jetbrains/jps/ModuleChunk.java b/jps/jps-builders/src/org/jetbrains/jps/ModuleChunk.java
index 683a8b02abb0..5f74fa20db0d 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/ModuleChunk.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/ModuleChunk.java
@@ -50,6 +50,21 @@ public class ModuleChunk {
myContainsTests = containsTests;
}
+ public String getPresentableShortName() {
+ String name = myModules.iterator().next().getName();
+ if (myModules.size() > 1) {
+ name += " and " + (myModules.size() - 1) + " more";
+ String fullName = getName();
+ if (fullName.length() < name.length()) {
+ name = fullName;
+ }
+ }
+ if (containsTests()) {
+ name = "tests of " + name;
+ }
+ return name;
+ }
+
public String getName() {
if (myModules.size() == 1) return myModules.iterator().next().getName();
return StringUtil.join(myModules, GET_NAME, ",");
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/EclipseCompilerTool.java b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/EclipseCompilerTool.java
new file mode 100644
index 000000000000..bea32c02b013
--- /dev/null
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/EclipseCompilerTool.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 org.jetbrains.jps.builders.impl.java;
+
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.builders.java.CannotCreateJavaCompilerException;
+import org.jetbrains.jps.builders.java.JavaCompilingTool;
+import org.jetbrains.jps.cmdline.ClasspathBootstrap;
+import org.jetbrains.jps.incremental.CompileContext;
+import org.jetbrains.jps.incremental.Utils;
+import org.jetbrains.jps.model.java.compiler.JavaCompilers;
+
+import javax.tools.*;
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+import java.util.ServiceLoader;
+
+/**
+ * @author nik
+ */
+public class EclipseCompilerTool extends JavaCompilingTool {
+ @NotNull
+ @Override
+ public String getId() {
+ return JavaCompilers.ECLIPSE_ID;
+ }
+
+ @Nullable
+ @Override
+ public String getAlternativeId() {
+ return JavaCompilers.ECLIPSE_EMBEDDED_ID;
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Eclipse compiler";
+ }
+
+ @NotNull
+ @Override
+ public JavaCompiler createCompiler() throws CannotCreateJavaCompilerException {
+ for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) {
+ if ("EclipseCompiler".equals(StringUtil.getShortName(javaCompiler.getClass()))) {
+ return javaCompiler;
+ }
+ }
+ throw new CannotCreateJavaCompilerException("Eclipse Batch Compiler was not found in classpath");
+ }
+
+ @NotNull
+ @Override
+ public List<File> getAdditionalClasspath() {
+ for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) { // Eclipse compiler
+ final File compilerResource = ClasspathBootstrap.getResourceFile(javaCompiler.getClass());
+ final String name = compilerResource.getName();
+ if (name.startsWith("ecj-") && name.endsWith(".jar")) {
+ return Collections.singletonList(compilerResource);
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void processCompilerOptions(@NotNull CompileContext context, @NotNull List<String> options) {
+ for (String option : options) {
+ if (option.startsWith("-proceedOnError")) {
+ Utils.PROCEED_ON_ERROR_KEY.set(context, Boolean.TRUE);
+ break;
+ }
+ }
+ }
+
+ @Override
+ public List<String> getDefaultCompilerOptions() {
+ return Collections.singletonList("-noExit");
+ }
+}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/JavacCompilerTool.java b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/JavacCompilerTool.java
new file mode 100644
index 000000000000..976e750fe15d
--- /dev/null
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/JavacCompilerTool.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.builders.impl.java;
+
+import com.intellij.util.ExceptionUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.builders.java.CannotCreateJavaCompilerException;
+import org.jetbrains.jps.builders.java.JavaCompilingTool;
+import org.jetbrains.jps.javac.JavacMain;
+import org.jetbrains.jps.model.java.compiler.JavaCompilers;
+
+import javax.tools.*;
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class JavacCompilerTool extends JavaCompilingTool {
+ @NotNull
+ @Override
+ public String getId() {
+ return JavaCompilers.JAVAC_ID;
+ }
+
+ @Nullable
+ @Override
+ public String getAlternativeId() {
+ return JavaCompilers.JAVAC_API_ID;
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "javac " + System.getProperty("java.version");
+ }
+
+ @NotNull
+ @Override
+ public JavaCompiler createCompiler() throws CannotCreateJavaCompilerException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler != null) {
+ return compiler;
+ }
+
+ String message = "System Java Compiler was not found in classpath";
+ // trying to obtain additional diagnostic for the case when compiler.jar is present, but there were problems with compiler class loading:
+ try {
+ Class.forName("com.sun.tools.javac.api.JavacTool", false, JavacMain.class.getClassLoader());
+ }
+ catch (Throwable ex) {
+ message = message + ":\n" + ExceptionUtil.getThrowableText(ex);
+ }
+ throw new CannotCreateJavaCompilerException(message);
+ }
+
+ @NotNull
+ @Override
+ public List<File> getAdditionalClasspath() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<String> getDefaultCompilerOptions() {
+ return Collections.singletonList("-implicit:class");
+ }
+}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/CannotCreateJavaCompilerException.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/CannotCreateJavaCompilerException.java
new file mode 100644
index 000000000000..4901a970f3a7
--- /dev/null
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/CannotCreateJavaCompilerException.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.jps.builders.java;
+
+/**
+ * @author nik
+ */
+public class CannotCreateJavaCompilerException extends Exception {
+ public CannotCreateJavaCompilerException(String message) {
+ super(message);
+ }
+}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java
index 35de6680ca87..1f0cd41c7ffa 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.ProjectPaths;
import org.jetbrains.jps.builders.BuildRootIndex;
@@ -38,6 +39,7 @@ import org.jetbrains.jps.model.library.JpsTypedLibrary;
import org.jetbrains.jps.model.library.sdk.JpsSdk;
import org.jetbrains.jps.model.library.sdk.JpsSdkReference;
import org.jetbrains.jps.model.module.JpsModule;
+import org.jetbrains.jps.service.JpsServiceManager;
import java.io.File;
import java.io.IOException;
@@ -79,7 +81,7 @@ public class JavaBuilderUtil {
final boolean errorsDetected = Utils.errorsDetected(context);
if (!isForcedRecompilationAllJavaModules(context)) {
if (context.shouldDifferentiate(chunk)) {
- context.processMessage(new ProgressMessage("Checking dependencies... [" + chunk.getName() + "]"));
+ context.processMessage(new ProgressMessage("Checking dependencies... [" + chunk.getPresentableShortName() + "]"));
final Set<File> allCompiledFiles = getAllCompiledFilesContainer(context);
final Set<File> allAffectedFiles = getAllAffectedFilesContainer(context);
@@ -144,7 +146,7 @@ public class JavaBuilderUtil {
}
}
else {
- final String messageText = "Marking " + chunk.getName() + " and direct dependants for recompilation";
+ final String messageText = "Marking " + chunk.getPresentableShortName() + " and direct dependants for recompilation";
LOG.info("Non-incremental mode: " + messageText);
context.processMessage(new ProgressMessage(messageText));
@@ -172,7 +174,7 @@ public class JavaBuilderUtil {
return false;
}
- context.processMessage(new ProgressMessage("Updating dependency information... [" + chunk.getName() + "]"));
+ context.processMessage(new ProgressMessage("Updating dependency information... [" + chunk.getPresentableShortName() + "]"));
globalMappings.integrate(delta);
@@ -281,6 +283,16 @@ public class JavaBuilderUtil {
return sdkLibrary.getProperties();
}
+ @Nullable
+ public static JavaCompilingTool findCompilingTool(@NotNull String compilerId) {
+ for (JavaCompilingTool tool : JpsServiceManager.getInstance().getExtensions(JavaCompilingTool.class)) {
+ if (compilerId.equals(tool.getId()) || compilerId.equals(tool.getAlternativeId())) {
+ return tool;
+ }
+ }
+ return null;
+ }
+
private static class ModulesBasedFileFilter implements Mappings.DependentFilesFilter {
private final CompileContext myContext;
private final Set<JpsModule> myChunkModules;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaCompilingTool.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaCompilingTool.java
new file mode 100644
index 000000000000..6728cf3c4a20
--- /dev/null
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaCompilingTool.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.jps.builders.java;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.incremental.CompileContext;
+
+import javax.tools.*;
+import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class JavaCompilingTool {
+ @NotNull
+ public abstract String getId();
+
+ @Nullable
+ public String getAlternativeId() {
+ return null;
+ }
+
+ @NotNull
+ public abstract String getDescription();
+
+ @NotNull
+ public abstract JavaCompiler createCompiler() throws CannotCreateJavaCompilerException;
+
+ @NotNull
+ public abstract List<File> getAdditionalClasspath();
+
+ public void processCompilerOptions(@NotNull CompileContext context, @NotNull List<String> options) {
+ }
+
+ public void prepareCompilationTask(@NotNull JavaCompiler.CompilationTask task, @NotNull Collection<String> options) {
+ }
+
+ public List<String> getDefaultCompilerOptions() {
+ return Collections.emptyList();
+ }
+}
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 e104ffd7e630..21818f540cc7 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
@@ -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.
@@ -380,12 +380,12 @@ public class ClassRepr extends Proto {
public static DataExternalizer<ClassRepr> externalizer(final DependencyContext context) {
return new DataExternalizer<ClassRepr>() {
@Override
- public void save(final DataOutput out, final ClassRepr value) throws IOException {
+ public void save(@NotNull final DataOutput out, final ClassRepr value) throws IOException {
value.save(out);
}
@Override
- public ClassRepr read(final DataInput in) throws IOException {
+ public ClassRepr read(@NotNull final DataInput in) throws IOException {
return new ClassRepr(context, in);
}
};
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/FieldRepr.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/FieldRepr.java
index b72e5aa18d5b..92359612f034 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/FieldRepr.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/FieldRepr.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.
@@ -16,6 +16,7 @@
package org.jetbrains.jps.builders.java.dependencyView;
import com.intellij.util.io.DataExternalizer;
+import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
@@ -57,12 +58,12 @@ class FieldRepr extends ProtoMember {
public static DataExternalizer<FieldRepr> externalizer(final DependencyContext context) {
return new DataExternalizer<FieldRepr>() {
@Override
- public void save(final DataOutput out, final FieldRepr value) throws IOException {
+ public void save(@NotNull final DataOutput out, final FieldRepr value) throws IOException {
value.save(out);
}
@Override
- public FieldRepr read(final DataInput in) throws IOException {
+ public FieldRepr read(@NotNull final DataInput in) throws IOException {
return new FieldRepr(context, in);
}
};
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntIntPersistentMultiMaplet.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntIntPersistentMultiMaplet.java
index eb94639941ac..560c4cecc0fd 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntIntPersistentMultiMaplet.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntIntPersistentMultiMaplet.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.
@@ -256,7 +256,7 @@ class IntIntPersistentMultiMaplet extends IntIntMultiMaplet {
private static class IntSetExternalizer implements DataExternalizer<TIntHashSet> {
@Override
- public void save(final DataOutput out, final TIntHashSet value) throws IOException {
+ public void save(@NotNull final DataOutput out, final TIntHashSet value) throws IOException {
final Ref<IOException> exRef = new Ref<IOException>(null);
value.forEach(new TIntProcedure() {
@Override
@@ -278,7 +278,7 @@ class IntIntPersistentMultiMaplet extends IntIntMultiMaplet {
}
@Override
- public TIntHashSet read(final DataInput in) throws IOException {
+ public TIntHashSet read(@NotNull final DataInput in) throws IOException {
final TIntHashSet result = new TIntHashSet();
final DataInputStream stream = (DataInputStream)in;
while (stream.available() > 0) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectPersistentMultiMaplet.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectPersistentMultiMaplet.java
index d195cbc4fc6f..3dd4d446c99a 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectPersistentMultiMaplet.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectPersistentMultiMaplet.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.
@@ -245,14 +245,14 @@ class IntObjectPersistentMultiMaplet<V extends Streamable> extends IntObjectMult
}
@Override
- public void save(final DataOutput out, final Collection<V> value) throws IOException {
+ public void save(@NotNull final DataOutput out, final Collection<V> value) throws IOException {
for (V x : value) {
myElementExternalizer.save(out, x);
}
}
@Override
- public Collection<V> read(final DataInput in) throws IOException {
+ public Collection<V> read(@NotNull final DataInput in) throws IOException {
final Collection<V> result = myCollectionFactory.create();
final DataInputStream stream = (DataInputStream)in;
while (stream.available() > 0) {
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 7b55ea7aaa29..72ad7557cd0b 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
@@ -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 org.jetbrains.jps.builders.java.dependencyView;
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;
@@ -159,12 +160,12 @@ class MethodRepr extends ProtoMember {
public static DataExternalizer<MethodRepr> externalizer(final DependencyContext context) {
return new DataExternalizer<MethodRepr>() {
@Override
- public void save(final DataOutput out, final MethodRepr value) throws IOException {
+ public void save(@NotNull final DataOutput out, final MethodRepr value) throws IOException {
value.save(out);
}
@Override
- public MethodRepr read(DataInput in) throws IOException {
+ public MethodRepr read(@NotNull DataInput in) throws IOException {
return new MethodRepr(context, in);
}
};
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ObjectObjectPersistentMultiMaplet.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ObjectObjectPersistentMultiMaplet.java
index d94d092b13d1..26a9b7a5756f 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ObjectObjectPersistentMultiMaplet.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ObjectObjectPersistentMultiMaplet.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.
@@ -245,14 +245,14 @@ public class ObjectObjectPersistentMultiMaplet<K, V extends Streamable> extends
}
@Override
- public void save(final DataOutput out, final Collection<V> value) throws IOException {
+ public void save(@NotNull final DataOutput out, final Collection<V> value) throws IOException {
for (V x : value) {
myElementExternalizer.save(out, x);
}
}
@Override
- public Collection<V> read(final DataInput in) throws IOException {
+ public Collection<V> read(@NotNull final DataInput in) throws IOException {
final Collection<V> result = myCollectionFactory.create();
final DataInputStream stream = (DataInputStream)in;
while (stream.available() > 0) {
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 dbdb7a9f1179..af85d75f344f 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
@@ -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 org.jetbrains.jps.builders.java.dependencyView;
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;
@@ -280,12 +281,12 @@ class TypeRepr {
public static DataExternalizer<AbstractType> externalizer(final DependencyContext context) {
return new DataExternalizer<AbstractType>() {
@Override
- public void save(final DataOutput out, final AbstractType value) throws IOException {
+ public void save(@NotNull final DataOutput out, final AbstractType value) throws IOException {
value.save(out);
}
@Override
- public AbstractType read(final DataInput in) throws IOException {
+ public AbstractType read(@NotNull final DataInput in) throws IOException {
AbstractType elementType;
int level = 0;
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 8db8bbc11ec4..a6b6bdd143f5 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
@@ -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.util.io.DataExternalizer;
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;
@@ -505,12 +506,12 @@ class UsageRepr {
public static class AnnotationUsage extends Usage {
public static final DataExternalizer<ElemType> elementTypeExternalizer = new DataExternalizer<ElemType>() {
@Override
- public void save(final DataOutput out, final ElemType value) throws IOException {
+ public void save(@NotNull final DataOutput out, final ElemType value) throws IOException {
DataInputOutputUtil.writeINT(out, value.ordinal());
}
@Override
- public ElemType read(final DataInput in) throws IOException {
+ public ElemType read(@NotNull final DataInput in) throws IOException {
final int ordinal = DataInputOutputUtil.readINT(in);
for (ElemType value : ElemType.values()) {
if (value.ordinal() == ordinal) {
@@ -699,12 +700,12 @@ class UsageRepr {
public static DataExternalizer<Usage> externalizer(final DependencyContext context) {
return new DataExternalizer<Usage>() {
@Override
- public void save(final DataOutput out, final Usage value) throws IOException {
+ public void save(@NotNull final DataOutput out, final Usage value) throws IOException {
value.save(out);
}
@Override
- public Usage read(DataInput in) throws IOException {
+ public Usage read(@NotNull DataInput in) throws IOException {
final byte tag = in.readByte();
switch (tag) {
case CLASS_USAGE:
diff --git a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/TObjectIntHashMapExternalizer.java b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/TObjectIntHashMapExternalizer.java
index c75414079b86..eed818e08567 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/TObjectIntHashMapExternalizer.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/TObjectIntHashMapExternalizer.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 org.jetbrains.jps.classFilesIndex;
import com.intellij.util.io.DataExternalizer;
import gnu.trove.TObjectIntHashMap;
import gnu.trove.TObjectIntProcedure;
+import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
@@ -34,7 +35,7 @@ public class TObjectIntHashMapExternalizer<K> implements DataExternalizer<TObjec
}
@Override
- public void save(final DataOutput out, final TObjectIntHashMap<K> map) throws IOException {
+ public void save(@NotNull final DataOutput out, final TObjectIntHashMap<K> map) throws IOException {
out.writeInt(map.size());
try {
map.forEachEntry(new TObjectIntProcedure<K>() {
@@ -57,7 +58,7 @@ public class TObjectIntHashMapExternalizer<K> implements DataExternalizer<TObjec
}
@Override
- public TObjectIntHashMap<K> read(final DataInput in) throws IOException {
+ public TObjectIntHashMap<K> read(@NotNull final DataInput in) throws IOException {
final int size = in.readInt();
final TObjectIntHashMap<K> map = new TObjectIntHashMap<K>(size);
for (int i = 0; i < size; i++) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/storage/ClassFilesIndexStorageBase.java b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/storage/ClassFilesIndexStorageBase.java
index 4d2b60446b52..1eba7b5f9512 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/storage/ClassFilesIndexStorageBase.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/storage/ClassFilesIndexStorageBase.java
@@ -163,7 +163,7 @@ public class ClassFilesIndexStorageBase<K, V> {
private static <V> DataExternalizer<CompiledDataValueContainer<V>> createValueContainerExternalizer(final DataExternalizer<V> valueExternalizer) {
return new DataExternalizer<CompiledDataValueContainer<V>>() {
@Override
- public void save(final DataOutput out, final CompiledDataValueContainer<V> value) throws IOException {
+ public void save(@NotNull final DataOutput out, final CompiledDataValueContainer<V> value) throws IOException {
final TIntObjectHashMap<V> underlying = value.myUnderlying;
out.writeInt(underlying.size());
final IOException[] ioException = {null};
@@ -187,7 +187,7 @@ public class ClassFilesIndexStorageBase<K, V> {
}
@Override
- public CompiledDataValueContainer<V> read(final DataInput in) throws IOException {
+ public CompiledDataValueContainer<V> read(@NotNull final DataInput in) throws IOException {
final TIntObjectHashMap<V> map = new TIntObjectHashMap<V>();
final int size = in.readInt();
for (int i = 0; i < size; i++) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/impl/EnumeratedMethodIncompleteSignature.java b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/impl/EnumeratedMethodIncompleteSignature.java
index fec5e9acccd7..b93a7da728f5 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/impl/EnumeratedMethodIncompleteSignature.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/impl/EnumeratedMethodIncompleteSignature.java
@@ -53,14 +53,14 @@ public class EnumeratedMethodIncompleteSignature {
public static DataExternalizer<EnumeratedMethodIncompleteSignature> createDataExternalizer() {
return new DataExternalizer<EnumeratedMethodIncompleteSignature>() {
@Override
- public void save(final DataOutput out, final EnumeratedMethodIncompleteSignature value) throws IOException {
+ public void save(@NotNull final DataOutput out, final EnumeratedMethodIncompleteSignature value) throws IOException {
out.writeInt(value.getOwner());
out.writeInt(value.getName());
out.writeBoolean(value.isStatic());
}
@Override
- public EnumeratedMethodIncompleteSignature read(final DataInput in) throws IOException {
+ public EnumeratedMethodIncompleteSignature read(@NotNull final DataInput in) throws IOException {
return new EnumeratedMethodIncompleteSignature(in.readInt(),
in.readInt(),
in.readBoolean());
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 d2b4c7f3210b..c89cb50397fb 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java
@@ -32,15 +32,14 @@ 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 javax.tools.JavaCompiler;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
+import javax.tools.*;
import java.io.File;
import java.lang.reflect.Method;
import java.util.*;
@@ -177,7 +176,7 @@ public class ClasspathBootstrap {
}
}
- public static List<File> getJavacServerClasspath(String sdkHome, boolean useEclipseCompiler) {
+ public static List<File> getJavacServerClasspath(String sdkHome, JavaCompilingTool compilingTool) {
final Set<File> cp = new LinkedHashSet<File>();
cp.add(getResourceFile(JavacServer.class)); // self
// util
@@ -236,16 +235,7 @@ public class ClasspathBootstrap {
}
}
- if (useEclipseCompiler) {
- // eclipse compiler
- for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) { // Eclipse compiler
- final File compilerResource = getResourceFile(javaCompiler.getClass());
- final String name = compilerResource.getName();
- if (name.startsWith("ecj-") && name.endsWith(".jar")) {
- cp.add(compilerResource);
- }
- }
- }
+ cp.addAll(compilingTool.getAdditionalClasspath());
final Class<JavaSourceTransformer> transformerClass = JavaSourceTransformer.class;
final ServiceLoader<JavaSourceTransformer> loader = ServiceLoader.load(transformerClass, transformerClass.getClassLoader());
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactOutputToSourceMapping.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactOutputToSourceMapping.java
index 572433552d65..fa022448ef73 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactOutputToSourceMapping.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactOutputToSourceMapping.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.util.SmartList;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.IOUtil;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.incremental.storage.AbstractStateStorage;
import org.jetbrains.jps.incremental.storage.PathStringDescriptor;
@@ -85,7 +86,7 @@ public class ArtifactOutputToSourceMapping extends AbstractStateStorage<String,
private final byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer();
@Override
- public void save(DataOutput out, List<SourcePathAndRootIndex> value) throws IOException {
+ public void save(@NotNull DataOutput out, List<SourcePathAndRootIndex> value) throws IOException {
for (SourcePathAndRootIndex pair : value) {
IOUtil.writeUTFFast(myBuffer, out, pair.myPath);
out.writeInt(pair.getRootIndex());
@@ -93,7 +94,7 @@ public class ArtifactOutputToSourceMapping extends AbstractStateStorage<String,
}
@Override
- public List<SourcePathAndRootIndex> read(DataInput in) throws IOException {
+ public List<SourcePathAndRootIndex> read(@NotNull DataInput in) throws IOException {
List<SourcePathAndRootIndex> result = new SmartList<SourcePathAndRootIndex>();
final DataInputStream stream = (DataInputStream)in;
while (stream.available() > 0) {
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 092b002f2384..af1c974b84a2 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
@@ -74,7 +74,7 @@ public abstract class ClassProcessingBuilder extends ModuleLevelBuilder {
final String progress = getProgressMessage();
final boolean shouldShowProgress = !StringUtil.isEmptyOrSpaces(progress);
if (shouldShowProgress) {
- context.processMessage(new ProgressMessage(progress + " [" + chunk.getName() + "]"));
+ context.processMessage(new ProgressMessage(progress + " [" + chunk.getPresentableShortName() + "]"));
}
ExitCode exitCode = ExitCode.NOTHING_DONE;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java
index 645cdd648bbb..db1700c47cbd 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java
@@ -39,6 +39,7 @@ import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.FileProcessor;
import org.jetbrains.jps.builders.java.JavaBuilderExtension;
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
+import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
import org.jetbrains.jps.builders.java.dependencyView.Callbacks;
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
@@ -81,7 +82,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
public static final boolean USE_EMBEDDED_JAVAC = System.getProperty(GlobalOptions.USE_EXTERNAL_JAVAC_OPTION) == null;
private static final Key<Integer> JAVA_COMPILER_VERSION_KEY = Key.create("_java_compiler_version_");
public static final Key<Boolean> IS_ENABLED = Key.create("_java_compiler_enabled_");
- private static final Key<Boolean> IS_COMPILER_API_SUPPORTED = Key.create("_java_compiler_api_supported_");
+ private static final Key<JavaCompilingTool> COMPILING_TOOL = Key.create("_java_compiling_tool_");
private static final Key<AtomicReference<String>> COMPILER_VERSION_INFO = Key.create("_java_compiler_version_info_");
private static final Set<String> FILTERED_OPTIONS = new HashSet<String>(Arrays.<String>asList(
@@ -137,16 +138,9 @@ public class JavaBuilder extends ModuleLevelBuilder {
if (LOG.isDebugEnabled()) {
LOG.debug("Java compiler ID: " + compilerId);
}
- final boolean isJavac = JavaCompilers.JAVAC_ID.equalsIgnoreCase(compilerId) || JavaCompilers.JAVAC_API_ID.equalsIgnoreCase(compilerId);
- final boolean isEclipse = JavaCompilers.ECLIPSE_ID.equalsIgnoreCase(compilerId) || JavaCompilers.ECLIPSE_EMBEDDED_ID.equalsIgnoreCase(compilerId);
- IS_COMPILER_API_SUPPORTED.set(context, isJavac || isEclipse);
- String messageText = null;
- if (isJavac) {
- messageText = "Using javac " + System.getProperty("java.version") + " to compile java sources";
- }
- else if (isEclipse) {
- messageText = "Using eclipse compiler to compile java sources";
- }
+ JavaCompilingTool compilingTool = JavaBuilderUtil.findCompilingTool(compilerId);
+ COMPILING_TOOL.set(context, compilingTool);
+ String messageText = compilingTool != null ? "Using " + compilingTool.getDescription() + " to compile java sources" : null;
COMPILER_VERSION_INFO.set(context, new AtomicReference<String>(messageText));
}
@@ -159,16 +153,17 @@ public class JavaBuilder extends ModuleLevelBuilder {
@NotNull ModuleChunk chunk,
@NotNull DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
@NotNull OutputConsumer outputConsumer) throws ProjectBuildException, IOException {
- if (!IS_ENABLED.get(context, Boolean.TRUE) || !IS_COMPILER_API_SUPPORTED.get(context, Boolean.TRUE)) {
+ JavaCompilingTool compilingTool = COMPILING_TOOL.get(context);
+ if (!IS_ENABLED.get(context, Boolean.TRUE) || compilingTool == null) {
return ExitCode.NOTHING_DONE;
}
- return doBuild(context, chunk, dirtyFilesHolder, outputConsumer);
+ return doBuild(context, chunk, dirtyFilesHolder, outputConsumer, compilingTool);
}
public ExitCode doBuild(@NotNull CompileContext context,
@NotNull ModuleChunk chunk,
@NotNull DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
- @NotNull OutputConsumer outputConsumer) throws ProjectBuildException, IOException {
+ @NotNull OutputConsumer outputConsumer, JavaCompilingTool compilingTool) throws ProjectBuildException, IOException {
try {
final Set<File> filesToCompile = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
@@ -190,7 +185,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
}
- return compile(context, chunk, dirtyFilesHolder, filesToCompile, outputConsumer);
+ return compile(context, chunk, dirtyFilesHolder, filesToCompile, outputConsumer, compilingTool);
}
catch (BuildDataCorruptedException e) {
throw e;
@@ -224,7 +219,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
ModuleChunk chunk,
DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
Collection<File> files,
- OutputConsumer outputConsumer)
+ OutputConsumer outputConsumer, @NotNull JavaCompilingTool compilingTool)
throws Exception {
ExitCode exitCode = ExitCode.NOTHING_DONE;
@@ -243,7 +238,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
// begin compilation round
final Mappings delta = pd.dataManager.getMappings().createDelta();
final Callbacks.Backend mappingsCallback = delta.getCallback();
- final OutputFilesSink outputSink = new OutputFilesSink(context, outputConsumer, mappingsCallback, chunk.getName());
+ final OutputFilesSink outputSink = new OutputFilesSink(context, outputConsumer, mappingsCallback, chunk.getPresentableShortName());
try {
if (hasSourcesToCompile) {
final AtomicReference<String> ref = COMPILER_VERSION_INFO.get(context);
@@ -264,7 +259,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
final DiagnosticSink diagnosticSink = new DiagnosticSink(context);
final String chunkName = chunk.getName();
- context.processMessage(new ProgressMessage("Parsing java... [" + chunkName + "]"));
+ context.processMessage(new ProgressMessage("Parsing java... [" + chunk.getPresentableShortName() + "]"));
final int filesCount = files.size();
boolean compiledOk = true;
@@ -284,7 +279,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
}
try {
- compiledOk = compileJava(context, chunk, files, classpath, platformCp, srcPath, diagnosticSink, outputSink);
+ compiledOk = compileJava(context, chunk, files, classpath, platformCp, srcPath, diagnosticSink, outputSink, compilingTool);
}
finally {
// heuristic: incorrect paths data recovery, so that the next make should not contain non-existing sources in 'recompile' list
@@ -328,7 +323,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
Collection<File> platformCp,
Collection<File> sourcePath,
DiagnosticOutputConsumer diagnosticSink,
- final OutputFileConsumer outputSink) throws Exception {
+ final OutputFileConsumer outputSink, JavaCompilingTool compilingTool) throws Exception {
final TasksCounter counter = new TasksCounter();
COUNTER_KEY.set(context, counter);
@@ -372,7 +367,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
final Map<File, Set<File>> outs = buildOutputDirectoriesMap(context, chunk);
- final List<String> options = getCompilationOptions(context, chunk, profile);
+ final List<String> options = getCompilationOptions(context, chunk, profile, compilingTool);
final ClassProcessingConsumer classesConsumer = new ClassProcessingConsumer(context, outputSink);
if (LOG.isDebugEnabled()) {
LOG.debug("Compiling chunk [" + chunk.getName() + "] with options: \"" + StringUtil.join(options, " ") + "\"");
@@ -380,13 +375,11 @@ public class JavaBuilder extends ModuleLevelBuilder {
try {
final boolean rc;
if (USE_EMBEDDED_JAVAC) {
- final boolean useEclipse = useEclipseCompiler(context);
- rc = JavacMain.compile(
- options, files, classpath, platformCp, sourcePath, outs, diagnosticSink, classesConsumer, context.getCancelStatus(), useEclipse
- );
+ rc = JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnosticSink, classesConsumer,
+ context.getCancelStatus(), compilingTool);
}
else {
- final JavacServerClient client = ensureJavacServerLaunched(context);
+ final JavacServerClient client = ensureJavacServerLaunched(context, compilingTool);
final RequestFuture<JavacServerResponseHandler> future = client.sendCompileRequest(
options, files, classpath, platformCp, sourcePath, outs, diagnosticSink, classesConsumer
);
@@ -404,13 +397,6 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
}
- private static boolean useEclipseCompiler(CompileContext context) {
- JpsProject project = context.getProjectDescriptor().getProject();
- final JpsJavaCompilerConfiguration configuration = JpsJavaExtensionService.getInstance().getCompilerConfiguration(project);
- final String compilerId = configuration != null? configuration.getJavaCompilerId() : null;
- return JavaCompilers.ECLIPSE_ID.equalsIgnoreCase(compilerId) || JavaCompilers.ECLIPSE_EMBEDDED_ID.equalsIgnoreCase(compilerId);
- }
-
private void submitAsyncTask(final CompileContext context, final Runnable taskRunnable) {
final TasksCounter counter = COUNTER_KEY.get(context);
@@ -432,7 +418,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
});
}
- private static synchronized JavacServerClient ensureJavacServerLaunched(CompileContext context) throws Exception {
+ private static synchronized JavacServerClient ensureJavacServerLaunched(@NotNull CompileContext context, @NotNull JavaCompilingTool compilingTool) throws Exception {
final ExternalJavacDescriptor descriptor = ExternalJavacDescriptor.KEY.get(context);
if (descriptor != null) {
return descriptor.client;
@@ -445,7 +431,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
final String javaHome = SystemProperties.getJavaHome();
final BaseOSProcessHandler processHandler = JavacServerBootstrap.launchJavacServer(
- javaHome, heapSize, port, Utils.getSystemRoot(), getCompilationVMOptions(context), useEclipseCompiler(context)
+ javaHome, heapSize, port, Utils.getSystemRoot(), getCompilationVMOptions(context, compilingTool), compilingTool
);
final JavacServerClient client = new JavacServerClient();
try {
@@ -529,19 +515,22 @@ public class JavaBuilder extends ModuleLevelBuilder {
private static final Key<List<String>> JAVAC_VM_OPTIONS = Key.create("_javac_vm_options_");
private static final Key<String> USER_DEFINED_BYTECODE_TARGET = Key.create("_user_defined_bytecode_target_");
- private static List<String> getCompilationVMOptions(CompileContext context) {
+ private static List<String> getCompilationVMOptions(CompileContext context, JavaCompilingTool compilingTool) {
List<String> cached = JAVAC_VM_OPTIONS.get(context);
if (cached == null) {
- loadCommonJavacOptions(context);
+ loadCommonJavacOptions(context, compilingTool);
cached = JAVAC_VM_OPTIONS.get(context);
}
return cached;
}
- private static List<String> getCompilationOptions(CompileContext context, ModuleChunk chunk, @Nullable ProcessorConfigProfile profile) {
+ private static List<String> getCompilationOptions(CompileContext context,
+ ModuleChunk chunk,
+ @Nullable ProcessorConfigProfile profile,
+ @NotNull JavaCompilingTool compilingTool) {
List<String> cached = JAVAC_OPTIONS.get(context);
if (cached == null) {
- loadCommonJavacOptions(context);
+ loadCommonJavacOptions(context, compilingTool);
cached = JAVAC_OPTIONS.get(context);
assert cached != null : context;
}
@@ -701,7 +690,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
return javaVersion;
}
- private static void loadCommonJavacOptions(CompileContext context) {
+ private static void loadCommonJavacOptions(@NotNull CompileContext context, @NotNull JavaCompilingTool compilingTool) {
final List<String> options = new ArrayList<String>();
final List<String> vmOptions = new ArrayList<String>();
@@ -755,14 +744,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
}
- if (useEclipseCompiler(context)) {
- for (String option : options) {
- if (option.startsWith("-proceedOnError")) {
- Utils.PROCEED_ON_ERROR_KEY.set(context, Boolean.TRUE);
- break;
- }
- }
- }
+ compilingTool.processCompilerOptions(context, options);
JAVAC_OPTIONS.set(context, options);
JAVAC_VM_OPTIONS.set(context, vmOptions);
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/CompilerMessage.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/CompilerMessage.java
index 9d34bbb05366..2d40d9faf1e6 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/CompilerMessage.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/CompilerMessage.java
@@ -37,19 +37,19 @@ public class CompilerMessage extends BuildMessage {
private final long myLine;
private final long myColumn;
- public CompilerMessage(String compilerName, @NotNull Throwable internalError) {
+ public CompilerMessage(@NotNull String compilerName, @NotNull Throwable internalError) {
this(compilerName, Kind.ERROR, getTextFromThrowable(internalError), null, -1L, -1L, -1L, -1L, -1L);
}
- public CompilerMessage(String compilerName, Kind kind, String messageText) {
+ public CompilerMessage(@NotNull String compilerName, Kind kind, String messageText) {
this(compilerName, kind, messageText, null, -1L, -1L, -1L, -1L, -1L);
}
- public CompilerMessage(String compilerName, Kind kind, String messageText, String sourcePath) {
+ public CompilerMessage(@NotNull String compilerName, Kind kind, String messageText, String sourcePath) {
this(compilerName, kind, messageText, sourcePath, -1L, -1L, -1L, -1L, -1L);
}
- public CompilerMessage(String compilerName, Kind kind, String messageText,
+ public CompilerMessage(@NotNull String compilerName, Kind kind, String messageText,
@Nullable String sourcePath,
long problemBeginOffset,
long problemEndOffset,
@@ -66,6 +66,7 @@ public class CompilerMessage extends BuildMessage {
myColumn = locationColumn;
}
+ @NotNull
public String getCompilerName() {
return myCompilerName;
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/FileKeyDescriptor.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/FileKeyDescriptor.java
index f467dd27c929..c1c364c22b80 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/FileKeyDescriptor.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/FileKeyDescriptor.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 org.jetbrains.jps.incremental.storage;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.io.IOUtil;
import com.intellij.util.io.KeyDescriptor;
+import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
@@ -31,11 +32,11 @@ import java.io.IOException;
public final class FileKeyDescriptor implements KeyDescriptor<File> {
private final byte[] buffer = IOUtil.allocReadWriteUTFBuffer();
- public void save(DataOutput out, File value) throws IOException {
+ public void save(@NotNull DataOutput out, File value) throws IOException {
IOUtil.writeUTFFast(buffer, out, value.getPath());
}
- public File read(DataInput in) throws IOException {
+ public File read(@NotNull DataInput in) throws IOException {
return new File(IOUtil.readUTFFast(buffer, in));
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/OneToManyPathsMapping.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/OneToManyPathsMapping.java
index 2c0516327584..6e8eb8787e00 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/OneToManyPathsMapping.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/OneToManyPathsMapping.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.
@@ -83,13 +83,13 @@ public class OneToManyPathsMapping extends AbstractStateStorage<String, Collecti
private static class PathCollectionExternalizer implements DataExternalizer<Collection<String>> {
private final byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer();
- public void save(DataOutput out, Collection<String> value) throws IOException {
+ public void save(@NotNull DataOutput out, Collection<String> value) throws IOException {
for (String str : value) {
IOUtil.writeUTFFast(myBuffer, out, str);
}
}
- public Collection<String> read(DataInput in) throws IOException {
+ public Collection<String> read(@NotNull DataInput in) throws IOException {
final Set<String> result = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
final DataInputStream stream = (DataInputStream)in;
while (stream.available() > 0) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/TimestampStorage.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/TimestampStorage.java
index 9955c6a64c83..3ebb148ebb71 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/TimestampStorage.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/TimestampStorage.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.
@@ -113,7 +113,7 @@ public class TimestampStorage extends AbstractStateStorage<File, TimestampStorag
}
private static class StateExternalizer implements DataExternalizer<TimestampPerTarget[]> {
- public void save(DataOutput out, TimestampPerTarget[] value) throws IOException {
+ public void save(@NotNull DataOutput out, TimestampPerTarget[] value) throws IOException {
out.writeInt(value.length);
for (TimestampPerTarget target : value) {
out.writeInt(target.targetId);
@@ -121,7 +121,7 @@ public class TimestampStorage extends AbstractStateStorage<File, TimestampStorag
}
}
- public TimestampPerTarget[] read(DataInput in) throws IOException {
+ public TimestampPerTarget[] read(@NotNull DataInput in) throws IOException {
int size = in.readInt();
TimestampPerTarget[] targets = new TimestampPerTarget[size];
for (int i = 0; i < size; i++) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java
index d9c58323804b..450dea158675 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java
@@ -16,11 +16,13 @@
package org.jetbrains.jps.javac;
import com.intellij.openapi.util.SystemInfo;
-import com.intellij.util.ExceptionUtil;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.api.CanceledStatus;
+import org.jetbrains.jps.builders.impl.java.JavacCompilerTool;
+import org.jetbrains.jps.builders.java.CannotCreateJavaCompilerException;
+import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.builders.java.JavaSourceTransformer;
import org.jetbrains.jps.cmdline.ClasspathBootstrap;
import org.jetbrains.jps.incremental.LineOutputWriter;
@@ -45,8 +47,7 @@ public class JavacMain {
"-d", "-classpath", "-cp", "-bootclasspath"
));
private static final Set<String> FILTERED_SINGLE_OPTIONS = new HashSet<String>(Arrays.<String>asList(
- /*javac options*/ "-verbose", "-proc:only", "-implicit:class", "-implicit:none", "-Xprefer:newer", "-Xprefer:source",
- /*eclipse options*/"-noExit"
+ /*javac options*/ "-verbose", "-proc:only", "-implicit:class", "-implicit:none", "-Xprefer:newer", "-Xprefer:source"
));
public static boolean compile(Collection<String> options,
@@ -57,52 +58,29 @@ public class JavacMain {
Map<File, Set<File>> outputDirToRoots,
final DiagnosticOutputConsumer diagnosticConsumer,
final OutputFileConsumer outputSink,
- CanceledStatus canceledStatus, boolean useEclipseCompiler) {
- JavaCompiler compiler = null;
- if (useEclipseCompiler) {
- for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) {
- compiler = javaCompiler;
- break;
- }
- if (compiler == null) {
- diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, "Eclipse Batch Compiler was not found in classpath"));
- return false;
- }
- }
-
- final boolean nowUsingJavac;
- if (compiler == null) {
- compiler = ToolProvider.getSystemJavaCompiler();
- if (compiler == null) {
- String message = "System Java Compiler was not found in classpath";
- // trying to obtain additional diagnostic for the case when compiler.jar is present, but there were problems with compiler class loading:
- try {
- Class.forName("com.sun.tools.javac.api.JavacTool", false, JavacMain.class.getClassLoader());
- }
- catch (Throwable ex) {
- message = message + ":\n" + ExceptionUtil.getThrowableText(ex);
- }
- diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, message));
- return false;
- }
- nowUsingJavac = true;
+ CanceledStatus canceledStatus, @NotNull JavaCompilingTool compilingTool) {
+ JavaCompiler compiler;
+ try {
+ compiler = compilingTool.createCompiler();
}
- else {
- nowUsingJavac = false;
+ catch (CannotCreateJavaCompilerException e) {
+ diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, e.getMessage()));
+ return false;
}
for (File outputDir : outputDirToRoots.keySet()) {
outputDir.mkdirs();
}
-
+
final List<JavaSourceTransformer> transformers = getSourceTransformers();
- final JavacFileManager fileManager = new JavacFileManager(new ContextImpl(compiler, diagnosticConsumer, outputSink, canceledStatus, nowUsingJavac), transformers);
+ final boolean usingJavac = compilingTool instanceof JavacCompilerTool;
+ final JavacFileManager fileManager = new JavacFileManager(new ContextImpl(compiler, diagnosticConsumer, outputSink, canceledStatus, usingJavac), transformers);
fileManager.handleOption("-bootclasspath", Collections.singleton("").iterator()); // this will clear cached stuff
fileManager.handleOption("-extdirs", Collections.singleton("").iterator()); // this will clear cached stuff
fileManager.handleOption("-endorseddirs", Collections.singleton("").iterator()); // this will clear cached stuff
- final Collection<String> _options = prepareOptions(options, nowUsingJavac);
+ final Collection<String> _options = prepareOptions(options, compilingTool);
try {
fileManager.setOutputDirectories(outputDirToRoots);
@@ -115,7 +93,7 @@ public class JavacMain {
if (!classpath.isEmpty()) {
try {
fileManager.setLocation(StandardLocation.CLASS_PATH, classpath);
- if (!nowUsingJavac && !isOptionSet(options, "-processorpath")) {
+ if (!usingJavac && !isOptionSet(options, "-processorpath")) {
// for non-javac file manager ensure annotation processor path defaults to classpath
fileManager.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, classpath);
}
@@ -148,7 +126,7 @@ public class JavacMain {
//noinspection IOResourceOpenedButNotSafelyClosed
final LineOutputWriter out = new LineOutputWriter() {
protected void lineAvailable(String line) {
- if (nowUsingJavac) {
+ if (usingJavac) {
diagnosticConsumer.outputLineAvailable(line);
}
else {
@@ -169,6 +147,7 @@ public class JavacMain {
final JavaCompiler.CompilationTask task = compiler.getTask(
out, fileManager, diagnosticConsumer, _options, null, fileManager.getJavaFileObjectsFromFiles(sources)
);
+ compilingTool.prepareCompilationTask(task, _options);
//if (!IS_VM_6_VERSION) { //todo!
// // Do not add the processor for JDK 1.6 because of the bugs in javac
@@ -186,7 +165,7 @@ public class JavacMain {
}
finally {
fileManager.close();
- if (nowUsingJavac) {
+ if (usingJavac) {
cleanupJavacNameTable();
}
}
@@ -221,14 +200,9 @@ public class JavacMain {
return false;
}
- private static Collection<String> prepareOptions(final Collection<String> options, boolean usingJavac) {
+ private static Collection<String> prepareOptions(final Collection<String> options, @NotNull JavaCompilingTool compilingTool) {
final List<String> result = new ArrayList<String>();
- if (usingJavac) {
- result.add("-implicit:class"); // the option supported by javac only
- }
- else { // is Eclipse
- result.add("-noExit");
- }
+ result.addAll(compilingTool.getDefaultCompilerOptions());
boolean skip = false;
for (String option : options) {
if (FILTERED_OPTIONS.contains(option)) {
@@ -236,7 +210,7 @@ public class JavacMain {
continue;
}
if (!skip) {
- if (!FILTERED_SINGLE_OPTIONS.contains(option)) {
+ if (!FILTERED_SINGLE_OPTIONS.contains(option) && !compilingTool.getDefaultCompilerOptions().contains(option)) {
result.add(option);
}
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java
index b5dc9bad44fb..65c92e2ae76f 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java
@@ -29,6 +29,9 @@ import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import io.netty.util.concurrent.ImmediateEventExecutor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.api.CanceledStatus;
+import org.jetbrains.jps.builders.impl.java.JavacCompilerTool;
+import org.jetbrains.jps.builders.java.JavaBuilderUtil;
+import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.service.SharedThreadPool;
import javax.tools.*;
@@ -44,7 +47,7 @@ public class JavacServer {
public static final int DEFAULT_SERVER_PORT = 7878;
public static final String SERVER_SUCCESS_START_MESSAGE = "Javac server started successfully. Listening on port: ";
public static final String SERVER_ERROR_START_MESSAGE = "Error starting Javac Server: ";
- public static final String USE_ECLIPSE_COMPILER_PROPERTY = "use.eclipse.compiler";
+ public static final String JPS_JAVA_COMPILING_TOOL_PROPERTY = "jps.java.compiling.tool";
private ChannelRegistrar myChannelRegistrar;
@@ -153,7 +156,8 @@ public class JavacServer {
};
try {
- final boolean rc = JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnostic, outputSink, canceledStatus, System.getProperty(USE_ECLIPSE_COMPILER_PROPERTY) != null);
+ JavaCompilingTool tool = getCompilingTool();
+ final boolean rc = JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnostic, outputSink, canceledStatus, tool);
return JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createBuildCompletedResponse(rc));
}
catch (Throwable e) {
@@ -163,6 +167,17 @@ public class JavacServer {
}
}
+ private static JavaCompilingTool getCompilingTool() {
+ String property = System.getProperty(JPS_JAVA_COMPILING_TOOL_PROPERTY);
+ if (property != null) {
+ JavaCompilingTool tool = JavaBuilderUtil.findCompilingTool(property);
+ if (tool != null) {
+ return tool;
+ }
+ }
+ return new JavacCompilerTool();
+ }
+
private final Set<CancelHandler> myCancelHandlers = Collections.synchronizedSet(new HashSet<CancelHandler>());
public void cancelBuilds() {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java
index 40b646e9a8dc..bb66e9c6b09f 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.concurrency.Semaphore;
+import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.cmdline.ClasspathBootstrap;
import org.jetbrains.jps.service.SharedThreadPool;
@@ -44,7 +45,7 @@ public class JavacServerBootstrap {
int port,
File workingDir,
List<String> vmOptions,
- boolean useEclipseCompiler) throws Exception {
+ JavaCompilingTool compilingTool) throws Exception {
final List<String> cmdLine = new ArrayList<String>();
appendParam(cmdLine, getVMExecutablePath(sdkHomePath));
appendParam(cmdLine, "-XX:MaxPermSize=150m");
@@ -82,9 +83,7 @@ public class JavacServerBootstrap {
appendParam(cmdLine, "-Duser.region=" + region);
}
- if (useEclipseCompiler) {
- appendParam(cmdLine, "-D" + JavacServer.USE_ECLIPSE_COMPILER_PROPERTY);
- }
+ appendParam(cmdLine, "-D" + JavacServer.JPS_JAVA_COMPILING_TOOL_PROPERTY + "=" + compilingTool.getId());
// this will disable standard extensions to ensure javac is loaded from the right tools.jar
appendParam(cmdLine, "-Djava.ext.dirs=");
@@ -95,7 +94,7 @@ public class JavacServerBootstrap {
appendParam(cmdLine, "-classpath");
- final List<File> cp = ClasspathBootstrap.getJavacServerClasspath(sdkHomePath, useEclipseCompiler);
+ final List<File> cp = ClasspathBootstrap.getJavacServerClasspath(sdkHomePath, compilingTool);
final StringBuilder classpath = new StringBuilder();
for (File file : cp) {
if (classpath.length() > 0) {
@@ -156,17 +155,15 @@ public class JavacServerBootstrap {
public void onTextAvailable(ProcessEvent event, Key outputType) {
if (outputType == ProcessOutputTypes.STDERR) {
- try {
- final String text = event.getText();
- if (text != null) {
- if (text.contains(JavacServer.SERVER_SUCCESS_START_MESSAGE) || text.contains(JavacServer.SERVER_ERROR_START_MESSAGE)) {
- processHandler.removeProcessListener(this);
- serverStartMessage.set(text);
- }
+ final String text = event.getText();
+ if (text != null && (text.contains(JavacServer.SERVER_SUCCESS_START_MESSAGE) || text.contains(JavacServer.SERVER_ERROR_START_MESSAGE))) {
+ try {
+ processHandler.removeProcessListener(this);
+ serverStartMessage.set(text);
+ }
+ finally {
+ semaphore.up();
}
- }
- finally {
- semaphore.up();
}
}
}
diff --git a/jps/model-impl/jps-model-impl.iml b/jps/model-impl/jps-model-impl.iml
index 5e72944c0f30..447c25cc7583 100644
--- a/jps/model-impl/jps-model-impl.iml
+++ b/jps/model-impl/jps-model-impl.iml
@@ -4,13 +4,11 @@
<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="util" />
<orderEntry type="module" module-name="jps-model-api" />
- <orderEntry type="module" module-name="testFramework" scope="TEST" />
</component>
</module>
diff --git a/jps/model-impl/jps-model-tests.iml b/jps/model-impl/jps-model-tests.iml
new file mode 100644
index 000000000000..f42308922277
--- /dev/null
+++ b/jps/model-impl/jps-model-tests.iml
@@ -0,0 +1,14 @@
+<?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$/testSrc">
+ <sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="jps-model-impl" />
+ <orderEntry type="module" module-name="testFramework" exported="" scope="TEST" />
+ </component>
+</module>
+
diff --git a/jps/model-serialization/jps-model-serialization.iml b/jps/model-serialization/jps-model-serialization.iml
index 988e3c506729..6859151b1bd5 100644
--- a/jps/model-serialization/jps-model-serialization.iml
+++ b/jps/model-serialization/jps-model-serialization.iml
@@ -4,15 +4,12 @@
<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="util" />
<orderEntry type="module" module-name="jps-model-api" />
<orderEntry type="library" exported="" name="JDOM" level="project" />
- <orderEntry type="module" module-name="jps-model-impl" exported="" scope="TEST" />
- <orderEntry type="module" module-name="testFramework" exported="" scope="TEST" />
</component>
</module>
diff --git a/jps/model-serialization/jps-serialization-tests.iml b/jps/model-serialization/jps-serialization-tests.iml
new file mode 100644
index 000000000000..953fef28dd82
--- /dev/null
+++ b/jps/model-serialization/jps-serialization-tests.iml
@@ -0,0 +1,14 @@
+<?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$/testSrc">
+ <sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="jps-model-serialization" />
+ <orderEntry type="module" module-name="jps-model-tests" exported="" scope="TEST" />
+ </component>
+</module>
+
diff --git a/lib/netty-all-5.0.0.Alpha1.jar b/lib/netty-all-5.0.0.Alpha2.jar
index ff0afa01af44..d4b646a22a83 100644
--- a/lib/netty-all-5.0.0.Alpha1.jar
+++ b/lib/netty-all-5.0.0.Alpha2.jar
Binary files differ
diff --git a/lib/required_for_dist.txt b/lib/required_for_dist.txt
index 2e7c8bfb3469..c368b9076142 100644
--- a/lib/required_for_dist.txt
+++ b/lib/required_for_dist.txt
@@ -40,7 +40,7 @@ microba.jar
miglayout-swing.jar
nanoxml-2.2.3.jar
nekohtml-1.9.14.jar
-netty-all-5.0.0.Alpha1.jar
+netty-all-5.0.0.Alpha2.jar
oromatcher.jar
picocontainer.jar
protobuf-2.5.0.jar
diff --git a/lib/src/netty-all-5.0.0.Alpha1-sources.jar b/lib/src/netty-all-5.0.0.Alpha2-sources.jar
index 767b4fb269df..354781d9601a 100644
--- a/lib/src/netty-all-5.0.0.Alpha1-sources.jar
+++ b/lib/src/netty-all-5.0.0.Alpha2-sources.jar
Binary files differ
diff --git a/native/runner/runnerw/runnerw.vcxproj b/native/runner/runnerw/runnerw.vcxproj
index c346390e3454..be49c0de94ec 100644
--- a/native/runner/runnerw/runnerw.vcxproj
+++ b/native/runner/runnerw/runnerw.vcxproj
@@ -23,7 +23,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v120</PlatformToolset>
+ <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/platform/bootstrap/src/com/intellij/idea/Main.java b/platform/bootstrap/src/com/intellij/idea/Main.java
index 5891ad6b3abb..05cbe635cf7d 100755
--- a/platform/bootstrap/src/com/intellij/idea/Main.java
+++ b/platform/bootstrap/src/com/intellij/idea/Main.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.
@@ -135,25 +135,26 @@ public class Main {
String platform = System.getProperty(PLATFORM_PREFIX_PROPERTY, "idea");
String patchFileName = ("jetbrains.patch.jar." + platform).toLowerCase();
String tempDir = System.getProperty("java.io.tmpdir");
- File originalPatchFile = new File(tempDir, patchFileName);
- File copyPatchFile = new File(tempDir, patchFileName + "_copy");
// always delete previous patch copy
- if (!FileUtilRt.delete(copyPatchFile)) {
- throw new IOException("Cannot create temporary patch file");
+ File patchCopy = new File(tempDir, patchFileName + "_copy");
+ File log4jCopy = new File(tempDir, "log4j.jar." + platform + "_copy");
+ if (!FileUtilRt.delete(patchCopy) || !FileUtilRt.delete(log4jCopy)) {
+ appendLog("Cannot delete temporary files in " + tempDir);
+ throw new IOException("Cannot delete temporary files in " + tempDir);
}
- appendLog("[Patch] Original patch %s: %s\n", originalPatchFile.exists() ? "exists" : "does not exist",
- originalPatchFile.getAbsolutePath());
-
- if (!originalPatchFile.exists()) {
- return;
- }
-
- if (!originalPatchFile.renameTo(copyPatchFile) || !FileUtilRt.delete(originalPatchFile)) {
- appendLog("[Patch] Cannot create temporary patch file\n");
- throw new IOException("Cannot create temporary patch file");
+ File patch = new File(tempDir, patchFileName);
+ appendLog("[Patch] Original patch %s: %s\n", patch.exists() ? "exists" : "does not exist",
+ patch.getAbsolutePath());
+ if (!patch.exists()) return;
+ File log4j = new File(PathManager.getLibPath(), "log4j.jar");
+ if (!log4j.exists()) {
+ appendLog("Log4J missing: " + log4j);
+ throw new IOException("Log4J missing: " + log4j);
}
+ copyFile(patch, patchCopy, true);
+ copyFile(log4j, log4jCopy, false);
int status = 0;
if (Restarter.isSupported()) {
@@ -168,13 +169,13 @@ public class Main {
System.getProperty("java.home") + "/bin/java".replace('/', File.separatorChar),
"-Xmx500m",
"-classpath",
- copyPatchFile.getPath() + File.pathSeparator +
- PathManager.getLibPath() + File.separator + "log4j.jar",
+ patchCopy.getPath() + File.pathSeparator + log4jCopy.getPath(),
"-Djava.io.tmpdir=" + tempDir,
+ "-Didea.updater.log=" + PathManager.getLogPath(),
+ "-Dswing.defaultlaf=" + UIManager.getSystemLookAndFeelClassName(),
"com.intellij.updater.Runner",
"install",
- PathManager.getHomePath(),
- PathManager.getLogPath());
+ PathManager.getHomePath());
appendLog("[Patch] Restarted cmd: %s\n", args.toString());
@@ -191,6 +192,20 @@ public class Main {
exit(status);
}
+ private static void copyFile(File original, File copy, boolean move) throws IOException {
+ if (move) {
+ if (!original.renameTo(copy) || !FileUtilRt.delete(original)) {
+ throw new IOException("Cannot create temporary file: " + copy);
+ }
+ }
+ else {
+ FileUtilRt.copy(original, copy);
+ if (!copy.exists()) {
+ throw new IOException("Cannot create temporary file: " + copy);
+ }
+ }
+ }
+
public static void showMessage(String title, Throwable t) {
StringWriter message = new StringWriter();
message.append("Internal error. Please report to http://");
diff --git a/platform/core-api/src/com/intellij/openapi/editor/colors/CodeInsightColors.java b/platform/core-api/src/com/intellij/openapi/editor/colors/CodeInsightColors.java
index d823f67b2a16..ede02461408d 100644
--- a/platform/core-api/src/com/intellij/openapi/editor/colors/CodeInsightColors.java
+++ b/platform/core-api/src/com/intellij/openapi/editor/colors/CodeInsightColors.java
@@ -32,13 +32,13 @@ public interface CodeInsightColors {
TextAttributesKey DEPRECATED_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("DEPRECATED_ATTRIBUTES");
TextAttributesKey LOCAL_VARIABLE_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("LOCAL_VARIABLE_ATTRIBUTES");
- TextAttributesKey REASSIGNED_LOCAL_VARIABLE_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("REASSIGNED_LOCAL_VARIABLE_ATTRIBUTES");
- TextAttributesKey REASSIGNED_PARAMETER_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("REASSIGNED_PARAMETER_ATTRIBUTES");
+ TextAttributesKey PARAMETER_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("PARAMETER_ATTRIBUTES");
+ TextAttributesKey REASSIGNED_LOCAL_VARIABLE_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("REASSIGNED_LOCAL_VARIABLE_ATTRIBUTES", LOCAL_VARIABLE_ATTRIBUTES);
+ TextAttributesKey REASSIGNED_PARAMETER_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("REASSIGNED_PARAMETER_ATTRIBUTES", PARAMETER_ATTRIBUTES);
TextAttributesKey IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES");
TextAttributesKey INSTANCE_FIELD_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("INSTANCE_FIELD_ATTRIBUTES");
TextAttributesKey STATIC_FIELD_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("STATIC_FIELD_ATTRIBUTES");
TextAttributesKey STATIC_FINAL_FIELD_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("STATIC_FINAL_FIELD_ATTRIBUTES", STATIC_FIELD_ATTRIBUTES);
- TextAttributesKey PARAMETER_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("PARAMETER_ATTRIBUTES");
TextAttributesKey CLASS_NAME_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("CLASS_NAME_ATTRIBUTES");
TextAttributesKey ANONYMOUS_CLASS_NAME_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("ANONYMOUS_CLASS_NAME_ATTRIBUTES");
TextAttributesKey TYPE_PARAMETER_NAME_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("TYPE_PARAMETER_NAME_ATTRIBUTES");
diff --git a/platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java b/platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java
index fa04c3c97062..6385e73f209e 100644
--- a/platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java
+++ b/platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java
@@ -62,6 +62,10 @@ public abstract class LanguageFileType implements FileType{
return null;
}
+ /**
+ * @deprecated implement own {@link com.intellij.debugger.engine.JVMDebugProvider} instead
+ */
+ @Deprecated
public boolean isJVMDebuggingSupported() {
return false;
}
diff --git a/platform/core-api/src/com/intellij/openapi/module/Module.java b/platform/core-api/src/com/intellij/openapi/module/Module.java
index b4218975311a..6120cb0d49d3 100644
--- a/platform/core-api/src/com/intellij/openapi/module/Module.java
+++ b/platform/core-api/src/com/intellij/openapi/module/Module.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.
@@ -107,8 +107,10 @@ public interface Module extends ComponentManager, AreaInstance, Disposable {
*
* @return scope including sources and tests, excluding libraries and dependencies.
*/
+ @NotNull
GlobalSearchScope getModuleScope();
+ @NotNull
GlobalSearchScope getModuleScope(boolean includeTests);
/**
@@ -116,6 +118,7 @@ public interface Module extends ComponentManager, AreaInstance, Disposable {
*
* @return scope including sources, tests, and libraries, excluding dependencies.
*/
+ @NotNull
GlobalSearchScope getModuleWithLibrariesScope();
/**
@@ -123,13 +126,20 @@ public interface Module extends ComponentManager, AreaInstance, Disposable {
*
* @return scope including sources, tests, and dependencies, excluding libraries.
*/
+ @NotNull
GlobalSearchScope getModuleWithDependenciesScope();
+ @NotNull
GlobalSearchScope getModuleContentScope();
+ @NotNull
GlobalSearchScope getModuleContentWithDependenciesScope();
+ @NotNull
GlobalSearchScope getModuleWithDependenciesAndLibrariesScope(boolean includeTests);
+ @NotNull
GlobalSearchScope getModuleWithDependentsScope();
+ @NotNull
GlobalSearchScope getModuleTestsWithDependentsScope();
+ @NotNull
GlobalSearchScope getModuleRuntimeScope(boolean includeTests);
}
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 8b67321dc6c8..e1c23aa071d8 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.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.
@@ -125,6 +125,7 @@ public abstract class VirtualFile extends UserDataHolderBase implements Modifica
* @return the path
*/
@SuppressWarnings("JavadocReference")
+ @NotNull
public abstract String getPath();
/**
@@ -727,4 +728,18 @@ public abstract class VirtualFile extends UserDataHolderBase implements Modifica
public static boolean isValidName(@NotNull String name) {
return name.indexOf('\\') < 0 && name.indexOf('/') < 0;
}
+
+ private static final Key<String> DETECTED_LINE_SEPARATOR_KEY = Key.create("DETECTED_LINE_SEPARATOR_KEY");
+
+ /**
+ * @return Line separator for this file.
+ * It is always null for directories and binaries, and possibly null if a separator isn't yet known.
+ * @see com.intellij.util.LineSeparator
+ */
+ public String getDetectedLineSeparator() {
+ return getUserData(DETECTED_LINE_SEPARATOR_KEY);
+ }
+ public void setDetectedLineSeparator(@Nullable String separator) {
+ putUserData(DETECTED_LINE_SEPARATOR_KEY, separator);
+ }
}
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/encoding/EncodingRegistry.java b/platform/core-api/src/com/intellij/openapi/vfs/encoding/EncodingRegistry.java
index 34907f8384c1..5a9a904e5758 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/encoding/EncodingRegistry.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/encoding/EncodingRegistry.java
@@ -53,6 +53,11 @@ public abstract class EncodingRegistry {
public abstract void setEncoding(@Nullable("null means project") VirtualFile virtualFileOrDir, @Nullable("null means remove mapping") Charset charset);
+ @Nullable("null means 'use system-default'")
+ public Charset getDefaultCharsetForPropertiesFiles(@Nullable VirtualFile virtualFile) {
+ return null;
+ }
+
public static EncodingRegistry getInstance() {
if (ourInstanceGetter == null) {
return (EncodingRegistry)ApplicationManager.getApplication().getPicoContainer().getComponentInstance("com.intellij.openapi.vfs.encoding.EncodingManager");
diff --git a/platform/core-api/src/com/intellij/psi/CommonClassNames.java b/platform/core-api/src/com/intellij/psi/CommonClassNames.java
index a7b6649666b4..32485e7a9066 100644
--- a/platform/core-api/src/com/intellij/psi/CommonClassNames.java
+++ b/platform/core-api/src/com/intellij/psi/CommonClassNames.java
@@ -61,6 +61,7 @@ public interface CommonClassNames {
@NonNls String JAVA_UTIL_LIST = "java.util.List";
@NonNls String JAVA_UTIL_ARRAY_LIST = "java.util.ArrayList";
@NonNls String JAVA_UTIL_SET = "java.util.Set";
+ @NonNls String JAVA_UTIL_HASH_SET = "java.util.HashSet";
@NonNls String JAVA_UTIL_PROPERTIES = "java.util.Properties";
@NonNls String JAVA_UTIL_PROPERTY_RESOURCE_BUNDLE = "java.util.PropertyResourceBundle";
@NonNls String JAVA_UTIL_DATE = "java.util.Date";
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 a94a146ba83a..836ad0c5a924 100644
--- a/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java
+++ b/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java
@@ -39,7 +39,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.search.GlobalSearchScope");
@Nullable private final Project myProject;
- protected GlobalSearchScope(Project project) {
+ protected GlobalSearchScope(@Nullable Project project) {
myProject = project;
}
@@ -49,6 +49,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
public abstract boolean contains(@NotNull VirtualFile file);
+ @Nullable
@Override
public Project getProject() {
return myProject;
diff --git a/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java b/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java
index d33ee461f1cb..bb6273bb5a7c 100644
--- a/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java
+++ b/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java
@@ -520,17 +520,27 @@ public class PsiTreeUtil {
@Nullable
@Contract("null, _, _ -> null")
public static <T extends PsiElement> T getParentOfType(@Nullable PsiElement element, @NotNull Class<T> aClass, boolean strict) {
- if (element == null) return null;
+ return getParentOfType(element, aClass, strict, -1);
+ }
+
+ @Contract("null, _, _, _ -> null")
+ public static <T extends PsiElement> T getParentOfType(@Nullable PsiElement element, @NotNull Class<T> aClass, boolean strict, int minStartOffset) {
+ if (element == null) {
+ return null;
+ }
+
if (strict) {
element = element.getParent();
}
- while (element != null) {
+ while (element != null && (minStartOffset == -1 || element.getNode().getStartOffset() >= minStartOffset)) {
if (aClass.isInstance(element)) {
//noinspection unchecked
return (T)element;
}
- if (element instanceof PsiFile) return null;
+ if (element instanceof PsiFile) {
+ return null;
+ }
element = element.getParent();
}
diff --git a/platform/core-api/src/com/intellij/testFramework/LightVirtualFile.java b/platform/core-api/src/com/intellij/testFramework/LightVirtualFile.java
index 158144a369b1..55222cff9448 100644
--- a/platform/core-api/src/com/intellij/testFramework/LightVirtualFile.java
+++ b/platform/core-api/src/com/intellij/testFramework/LightVirtualFile.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.
@@ -184,6 +184,7 @@ public class LightVirtualFile extends VirtualFile {
return myFileType;
}
+ @NotNull
@Override
public String getPath() {
return "/" + getName();
diff --git a/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java b/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
index 19854ccdb88e..5172e155cd14 100644
--- a/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
+++ b/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
@@ -24,7 +24,7 @@ public class PlatformUtilsCore {
public static final String APPCODE_PREFIX = "AppCode";
public static final String CPP_PREFIX = "CppIde";
public static final String PYCHARM_PREFIX = "Python";
- public static final String PYCHARM_PREFIX2 = "PyCharm";
+ public static final String PYCHARM_PREFIX2 = "PyCharmCore";
public static final String RUBY_PREFIX = "Ruby";
public static final String PHP_PREFIX = "PhpStorm";
public static final String WEB_PREFIX = "WebStorm";
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/ex/util/SegmentArray.java b/platform/core-impl/src/com/intellij/openapi/editor/ex/util/SegmentArray.java
index b3e91d67ad05..2918656a952b 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/ex/util/SegmentArray.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/ex/util/SegmentArray.java
@@ -27,8 +27,8 @@ import org.jetbrains.annotations.NotNull;
*/
public class SegmentArray {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.ex.util.SegmentArray");
- private int[] myStarts;
- private int[] myEnds;
+ protected int[] myStarts;
+ protected int[] myEnds;
protected int mySegmentCount = 0;
protected static final int INITIAL_SIZE = 64;
@@ -84,26 +84,32 @@ public class SegmentArray {
return newArray;
}
+ protected int noSegmentsAvailable(int offset) {
+ throw new IllegalStateException("no segments available. offset = " + offset);
+ }
+
+ protected int offsetOutOfRange(int offset, int lastValidOffset) {
+ throw new IndexOutOfBoundsException("Wrong offset: " + offset + ". Should be in range: [0, " + lastValidOffset + "]");
+ }
+
public final int findSegmentIndex(int offset) {
if (mySegmentCount <= 0) {
- if (offset == 0) return 0;
- throw new IllegalStateException("no segments available. offset = "+offset);
+ return offset == 0 ? 0 : noSegmentsAvailable(offset);
}
final int lastValidOffset = getLastValidOffset();
-
if (offset > lastValidOffset || offset < 0) {
- throw new IndexOutOfBoundsException("Wrong offset: " + offset + ". Should be in range: [0, " + lastValidOffset + "]");
+ return offsetOutOfRange(offset, lastValidOffset);
}
- final int lastValidIndex = mySegmentCount - 1;
- if (offset == lastValidOffset) return lastValidIndex;
+ int end = mySegmentCount - 1;
+ if (offset == lastValidOffset) {
+ return end;
+ }
int start = 0;
- int end = lastValidIndex;
-
- while (start < end) {
- int i = (start + end) / 2;
+ while (start <= end) {
+ int i = (start + end) >>> 1;
if (offset < myStarts[i]) {
end = i - 1;
}
@@ -115,9 +121,12 @@ public class SegmentArray {
}
}
+ return segmentNotFound(offset, start);
+ }
+
+ protected int segmentNotFound(int offset, int start) {
// This means that there is a gap at given offset
assert myStarts[start] <= offset && offset < myEnds[start] : start;
-
return start;
}
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 3d51b6ba470c..6be740bc6364 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
@@ -59,7 +59,8 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
private final List<RangeMarker> myGuardedBlocks = new ArrayList<RangeMarker>();
private ReadonlyFragmentModificationHandler myReadonlyFragmentModificationHandler;
- private final LineSet myLineSet = new LineSet();
+ private final Object myLineSetLock = new String("line set lock");
+ private volatile LineSet myLineSet;
private volatile ImmutableText myText;
private volatile SoftReference<String> myTextString;
@@ -110,9 +111,13 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
}
public DocumentImpl(@NotNull CharSequence chars, boolean forUseInNonAWTThread) {
+ this(chars, false, forUseInNonAWTThread);
+ }
+
+ public DocumentImpl(@NotNull CharSequence chars, boolean acceptSlashR, boolean forUseInNonAWTThread) {
+ setAcceptSlashR(acceptSlashR);
assertValidSeparators(chars);
myText = ImmutableText.valueOf(chars);
- myLineSet.documentCreated(this);
setCyclicBufferSize(0);
setModificationStamp(LocalTimeCounter.currentTime());
myAssertThreading = !forUseInNonAWTThread;
@@ -127,6 +132,22 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
}
}
+ private LineSet getLineSet() {
+ LineSet lineSet = myLineSet;
+ if (lineSet == null) {
+ synchronized (myLineSetLock) {
+ lineSet = myLineSet;
+ if (lineSet == null) {
+ lineSet = new LineSet();
+ lineSet.documentCreated(this);
+ myLineSet = lineSet;
+ }
+ }
+ }
+
+ return lineSet;
+ }
+
@Override
@NotNull
public char[] getChars() {
@@ -159,11 +180,12 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
CharSequence text = myText;
RangeMarker caretMarker = caretOffset < 0 || caretOffset > getTextLength() ? null : createRangeMarker(caretOffset, caretOffset);
try {
- for (int line = 0; line < myLineSet.getLineCount(); line++) {
- if (inChangedLinesOnly && !myLineSet.isModified(line)) continue;
+ LineSet lineSet = getLineSet();
+ for (int line = 0; line < lineSet.getLineCount(); line++) {
+ if (inChangedLinesOnly && !lineSet.isModified(line)) continue;
int whiteSpaceStart = -1;
- final int lineEnd = myLineSet.getLineEnd(line) - myLineSet.getSeparatorLength(line);
- int lineStart = myLineSet.getLineStart(line);
+ final int lineEnd = lineSet.getLineEnd(line) - lineSet.getSeparatorLength(line);
+ int lineStart = lineSet.getLineStart(line);
for (int offset = lineEnd - 1; offset >= lineStart; offset--) {
char c = text.charAt(offset);
if (c != ' ' && c != '\t') {
@@ -228,12 +250,13 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
markers.add(marker);
}
}
+ LineSet lineSet = getLineSet();
lineLoop:
- for (int line = 0; line < myLineSet.getLineCount(); line++) {
- if (inChangedLinesOnly && !myLineSet.isModified(line)) continue;
+ for (int line = 0; line < lineSet.getLineCount(); line++) {
+ if (inChangedLinesOnly && !lineSet.isModified(line)) continue;
int whiteSpaceStart = -1;
- final int lineEnd = myLineSet.getLineEnd(line) - myLineSet.getSeparatorLength(line);
- int lineStart = myLineSet.getLineStart(line);
+ final int lineEnd = lineSet.getLineEnd(line) - lineSet.getSeparatorLength(line);
+ int lineStart = lineSet.getLineStart(line);
for (int offset = lineEnd - 1; offset >= lineStart; offset--) {
char c = text.charAt(offset);
if (c != ' ' && c != '\t') {
@@ -644,19 +667,20 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
@Override
public void clearLineModificationFlags() {
- myLineSet.clearModificationFlags();
+ getLineSet().clearModificationFlags();
}
public void clearLineModificationFlagsExcept(@NotNull List<Integer> caretLines) {
List<Integer> modifiedLines = new ArrayList<Integer>(caretLines.size());
+ LineSet lineSet = getLineSet();
for (Integer line : caretLines) {
- if (line != null && line >= 0 && line < myLineSet.getLineCount() && myLineSet.isModified(line)) {
+ if (line != null && line >= 0 && line < lineSet.getLineCount() && lineSet.isModified(line)) {
modifiedLines.add(line);
}
}
clearLineModificationFlags();
for (Integer line : modifiedLines) {
- myLineSet.setModified(line);
+ lineSet.setModified(line);
}
}
@@ -694,6 +718,8 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
}
assertInsideCommand();
+ getLineSet(); // initialize line set to track changed lines
+
DocumentEvent event = new DocumentEventImpl(this, offset, oldString, newString, myModificationStamp, wholeTextReplaced);
if (!ShutDownTracker.isShutdownHookRunning()) {
@@ -725,7 +751,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
try {
if (LOG.isDebugEnabled()) LOG.debug(event.toString());
- myLineSet.changedUpdate(event);
+ getLineSet().changedUpdate(event);
setModificationStamp(newModificationStamp);
if (!ShutDownTracker.isShutdownHookRunning()) {
@@ -847,39 +873,39 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
@Override
public int getLineNumber(final int offset) {
- return myLineSet.findLineIndex(offset);
+ return getLineSet().findLineIndex(offset);
}
@Override
@NotNull
public LineIterator createLineIterator() {
- return myLineSet.createIterator();
+ return getLineSet().createIterator();
}
@Override
public final int getLineStartOffset(final int line) {
if (line == 0) return 0; // otherwise it crashed for zero-length document
- return myLineSet.getLineStart(line);
+ return getLineSet().getLineStart(line);
}
@Override
public final int getLineEndOffset(int line) {
if (getTextLength() == 0 && line == 0) return 0;
- int result = myLineSet.getLineEnd(line) - getLineSeparatorLength(line);
+ int result = getLineSet().getLineEnd(line) - getLineSeparatorLength(line);
assert result >= 0;
return result;
}
@Override
public final int getLineSeparatorLength(int line) {
- int separatorLength = myLineSet.getSeparatorLength(line);
+ int separatorLength = getLineSet().getSeparatorLength(line);
assert separatorLength >= 0;
return separatorLength;
}
@Override
public final int getLineCount() {
- int lineCount = myLineSet.getLineCount();
+ int lineCount = getLineSet().getLineCount();
assert lineCount >= 0;
return lineCount;
}
diff --git a/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java b/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java
index d621140f132b..a0baadbb8096 100644
--- a/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java
+++ b/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.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,7 +40,6 @@ import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
public final class LoadTextUtil {
- private static final Key<String> DETECTED_LINE_SEPARATOR_KEY = Key.create("DETECTED_LINE_SEPARATOR_KEY");
@Nls private static final String AUTO_DETECTED_FROM_BOM = "auto-detected from BOM";
private LoadTextUtil() {
@@ -215,7 +214,7 @@ public final class LoadTextUtil {
}
String newText = StringUtil.convertLineSeparators(currentText.toString(), newSeparator);
- file.putUserData(DETECTED_LINE_SEPARATOR_KEY, newSeparator);
+ file.setDetectedLineSeparator(newSeparator);
write(project, file, requestor, newText, -1);
}
@@ -346,13 +345,7 @@ public final class LoadTextUtil {
@NotNull
public static CharSequence loadText(@NotNull VirtualFile file) {
if (file instanceof LightVirtualFile) {
- CharSequence content = ((LightVirtualFile)file).getContent();
- if (StringUtil.indexOf(content, '\r') == -1) return content;
-
- CharBuffer buffer = CharBuffer.allocate(content.length());
- buffer.append(content);
- buffer.rewind();
- return convertLineSeparators(buffer).first;
+ return ((LightVirtualFile)file).getContent();
}
if (file.isDirectory()) {
@@ -397,7 +390,7 @@ public final class LoadTextUtil {
Pair<CharSequence, String> result = convertBytes(bytes, charset, offset);
if (saveDetectedSeparators) {
- virtualFile.putUserData(DETECTED_LINE_SEPARATOR_KEY, result.getSecond());
+ virtualFile.setDetectedLineSeparator(result.getSecond());
}
return result.getFirst();
}
@@ -425,7 +418,7 @@ public final class LoadTextUtil {
}
static String getDetectedLineSeparator(@NotNull VirtualFile file) {
- return file.getUserData(DETECTED_LINE_SEPARATOR_KEY);
+ return file.getDetectedLineSeparator();
}
@NotNull
diff --git a/platform/core-impl/src/com/intellij/openapi/module/impl/ModuleScopeProvider.java b/platform/core-impl/src/com/intellij/openapi/module/impl/ModuleScopeProvider.java
index 720c88d60233..58906e1b17ac 100644
--- a/platform/core-impl/src/com/intellij/openapi/module/impl/ModuleScopeProvider.java
+++ b/platform/core-impl/src/com/intellij/openapi/module/impl/ModuleScopeProvider.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.openapi.module.impl;
import com.intellij.psi.search.GlobalSearchScope;
+import org.jetbrains.annotations.NotNull;
/**
* Author: dmitrylomov
@@ -27,8 +28,10 @@ public interface ModuleScopeProvider {
*
* @return scope including sources and tests, excluding libraries and dependencies.
*/
+ @NotNull
GlobalSearchScope getModuleScope();
+ @NotNull
GlobalSearchScope getModuleScope(boolean includeTests);
/**
@@ -36,6 +39,7 @@ public interface ModuleScopeProvider {
*
* @return scope including sources, tests, and libraries, excluding dependencies.
*/
+ @NotNull
GlobalSearchScope getModuleWithLibrariesScope();
/**
@@ -43,14 +47,21 @@ public interface ModuleScopeProvider {
*
* @return scope including sources, tests, and dependencies, excluding libraries.
*/
+ @NotNull
GlobalSearchScope getModuleWithDependenciesScope();
+ @NotNull
GlobalSearchScope getModuleContentScope();
+ @NotNull
GlobalSearchScope getModuleContentWithDependenciesScope();
+ @NotNull
GlobalSearchScope getModuleWithDependenciesAndLibrariesScope(boolean includeTests);
+ @NotNull
GlobalSearchScope getModuleWithDependentsScope();
+ @NotNull
GlobalSearchScope getModuleTestsWithDependentsScope();
+ @NotNull
GlobalSearchScope getModuleRuntimeScope(boolean includeTests);
void clearCache();
diff --git a/platform/core-impl/src/com/intellij/openapi/vfs/impl/jar/CoreJarVirtualFile.java b/platform/core-impl/src/com/intellij/openapi/vfs/impl/jar/CoreJarVirtualFile.java
index 3827ecc2da66..1256c54f3f5d 100644
--- a/platform/core-impl/src/com/intellij/openapi/vfs/impl/jar/CoreJarVirtualFile.java
+++ b/platform/core-impl/src/com/intellij/openapi/vfs/impl/jar/CoreJarVirtualFile.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,11 +18,13 @@ package com.intellij.openapi.vfs.impl.jar;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileSystem;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.List;
/**
* @author yole
@@ -30,10 +32,10 @@ import java.util.ArrayList;
public class CoreJarVirtualFile extends VirtualFile {
private final CoreJarHandler myHandler;
private final VirtualFile myParent;
- private final ArrayList<VirtualFile> myChildren = new ArrayList<VirtualFile>();
+ private final List<VirtualFile> myChildren = new ArrayList<VirtualFile>();
private final JarHandlerBase.EntryInfo myEntry;
- public CoreJarVirtualFile(CoreJarHandler handler, JarHandlerBase.EntryInfo entry, CoreJarVirtualFile parent) {
+ public CoreJarVirtualFile(@NotNull CoreJarHandler handler, @NotNull JarHandlerBase.EntryInfo entry, @Nullable CoreJarVirtualFile parent) {
myHandler = handler;
myParent = parent;
myEntry = entry;
@@ -56,6 +58,7 @@ public class CoreJarVirtualFile extends VirtualFile {
}
@Override
+ @NotNull
public String getPath() {
if (myParent == null) return myHandler.myBasePath + "!/";
diff --git a/platform/core-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandlerBase.java b/platform/core-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandlerBase.java
index 4dba701485a1..0648e3d319e1 100644
--- a/platform/core-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandlerBase.java
+++ b/platform/core-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandlerBase.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 JarHandlerBase {
protected static class EntryInfo {
protected final boolean isDirectory;
+ @NotNull
protected final String shortName;
protected final EntryInfo parent;
diff --git a/platform/core-impl/src/com/intellij/openapi/vfs/local/CoreLocalVirtualFile.java b/platform/core-impl/src/com/intellij/openapi/vfs/local/CoreLocalVirtualFile.java
index c3b770af072b..016cab9a818b 100644
--- a/platform/core-impl/src/com/intellij/openapi/vfs/local/CoreLocalVirtualFile.java
+++ b/platform/core-impl/src/com/intellij/openapi/vfs/local/CoreLocalVirtualFile.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.
@@ -56,6 +56,7 @@ public class CoreLocalVirtualFile extends VirtualFile {
return myFileSystem;
}
+ @NotNull
@Override
public String getPath() {
return FileUtil.toSystemIndependentName(myIoFile.getAbsolutePath());
diff --git a/platform/dvcs/src/com/intellij/dvcs/DvcsCommitAdditionalComponent.java b/platform/dvcs/src/com/intellij/dvcs/DvcsCommitAdditionalComponent.java
index 56900785e57b..26c87c7de627 100644
--- a/platform/dvcs/src/com/intellij/dvcs/DvcsCommitAdditionalComponent.java
+++ b/platform/dvcs/src/com/intellij/dvcs/DvcsCommitAdditionalComponent.java
@@ -24,10 +24,13 @@ import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.CheckinProjectPanel;
+import com.intellij.openapi.vcs.FilePath;
+import com.intellij.openapi.vcs.FilePathImpl;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.NonFocusableCheckBox;
+import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -36,8 +39,9 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.Collection;
-import java.util.LinkedHashSet;
+import java.io.File;
+import java.util.*;
+import java.util.List;
/**
* @author Nadya Zabrodina
@@ -51,6 +55,7 @@ public abstract class DvcsCommitAdditionalComponent implements RefreshableOnComp
@Nullable private String myPreviousMessage;
@Nullable private String myAmendedMessage;
@NotNull protected final CheckinProjectPanel myCheckinPanel;
+ @Nullable private Map<VirtualFile, String> myMessagesForRoots;
public DvcsCommitAdditionalComponent(@NotNull final Project project, @NotNull CheckinProjectPanel panel) {
myCheckinPanel = panel;
@@ -76,14 +81,16 @@ public abstract class DvcsCommitAdditionalComponent implements RefreshableOnComp
@Override
public void actionPerformed(ActionEvent e) {
if (myAmend.isSelected()) {
- if (myPreviousMessage.equals(myCheckinPanel.getCommitMessage())) { // if user has already typed something, don't revert it
- if (myAmendedMessage == null) {
- loadMessageInModalTask(project);
+ if (myPreviousMessage.equals(myCheckinPanel.getCommitMessage())) { // if user has already typed something, don't revert it
+ if (myMessagesForRoots == null) {
+ loadMessagesInModalTask(project); //load all commit messages for all repositories
+ }
+ String message = constructAmendedMessage();
+ if (!StringUtil.isEmptyOrSpaces(message)) {
+ myAmendedMessage = message;
+ substituteCommitMessage(myAmendedMessage);
+ }
}
- else { // checkbox is selected not the first time
- substituteCommitMessage(myAmendedMessage);
- }
- }
}
else {
// there was the amended message, but user has changed it => not reverting
@@ -96,6 +103,20 @@ public abstract class DvcsCommitAdditionalComponent implements RefreshableOnComp
myPanel.add(myAmend, c);
}
+ private String constructAmendedMessage() {
+ Set<VirtualFile> selectedRoots = getVcsRoots(getSelectedFilePaths()); // get only selected files
+ LinkedHashSet<String> messages = ContainerUtil.newLinkedHashSet();
+ if (myMessagesForRoots != null) {
+ for (VirtualFile root : selectedRoots) {
+ String message = myMessagesForRoots.get(root);
+ if (message != null) {
+ messages.add(message);
+ }
+ }
+ }
+ return DvcsUtil.joinMessagesOrNull(messages);
+ }
+
public JComponent getComponent() {
return myPanel;
}
@@ -104,19 +125,15 @@ public abstract class DvcsCommitAdditionalComponent implements RefreshableOnComp
myAmend.setSelected(false);
}
- private void loadMessageInModalTask(@NotNull Project project) {
+ private void loadMessagesInModalTask(@NotNull Project project) {
try {
- String messageFromVcs =
- ProgressManager.getInstance().runProcessWithProgressSynchronously(new ThrowableComputable<String, VcsException>() {
+ myMessagesForRoots =
+ ProgressManager.getInstance().runProcessWithProgressSynchronously(new ThrowableComputable<Map<VirtualFile,String>, VcsException>() {
@Override
- public String compute() throws VcsException {
- return getLastCommitMessage();
+ public Map<VirtualFile, String> compute() throws VcsException {
+ return getLastCommitMessages();
}
}, "Reading commit message...", false, project);
- if (!StringUtil.isEmptyOrSpaces(messageFromVcs)) {
- substituteCommitMessage(messageFromVcs);
- myAmendedMessage = messageFromVcs;
- }
}
catch (VcsException e) {
Messages.showErrorDialog(getComponent(), "Couldn't load commit message of the commit to amend.\n" + e.getMessage(),
@@ -133,24 +150,32 @@ public abstract class DvcsCommitAdditionalComponent implements RefreshableOnComp
}
@Nullable
- private String getLastCommitMessage() throws VcsException {
- Collection<VirtualFile> roots = getRoots();
+ private Map<VirtualFile, String> getLastCommitMessages() throws VcsException {
+ Map<VirtualFile, String> messagesForRoots = new HashMap<VirtualFile, String>();
+ Collection<VirtualFile> roots = myCheckinPanel.getRoots(); //all committed vcs roots, not only selected
final Ref<VcsException> exception = Ref.create();
- LinkedHashSet<String> messages = ContainerUtil.newLinkedHashSet();
for (VirtualFile root : roots) {
String message = getLastCommitMessage(root);
- if (message != null) {
- messages.add(message);
- }
+ messagesForRoots.put(root, message);
}
if (!exception.isNull()) {
throw exception.get();
}
- return DvcsUtil.joinMessagesOrNull(messages);
+ return messagesForRoots;
+ }
+
+ @NotNull
+ private List<FilePath> getSelectedFilePaths() {
+ return ContainerUtil.map(myCheckinPanel.getFiles(), new Function<File, FilePath>() {
+ @Override
+ public FilePath fun(File file) {
+ return new FilePathImpl(file, file.isDirectory());
+ }
+ });
}
@NotNull
- protected abstract Collection<VirtualFile> getRoots();
+ protected abstract Set<VirtualFile> getVcsRoots(@NotNull Collection<FilePath> files);
@Nullable
protected abstract String getLastCommitMessage(@NotNull VirtualFile repo) throws VcsException;
diff --git a/platform/dvcs/testFramework/com/intellij/dvcs/test/MockVirtualFile.java b/platform/dvcs/testFramework/com/intellij/dvcs/test/MockVirtualFile.java
index 2b6743c09523..3b36381dcf85 100644
--- a/platform/dvcs/testFramework/com/intellij/dvcs/test/MockVirtualFile.java
+++ b/platform/dvcs/testFramework/com/intellij/dvcs/test/MockVirtualFile.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.
@@ -39,9 +39,9 @@ import java.io.OutputStream;
*/
public class MockVirtualFile extends VirtualFile {
- private static VirtualFileSystem ourFileSystem = new MockVirtualFileSystem();
+ private static final VirtualFileSystem ourFileSystem = new MockVirtualFileSystem();
- private String myPath;
+ private final String myPath;
@NotNull
static VirtualFile fromPath(@NotNull String absolutePath) {
@@ -84,6 +84,7 @@ public class MockVirtualFile extends VirtualFile {
return ourFileSystem;
}
+ @NotNull
@Override
public String getPath() {
return myPath;
@@ -179,14 +180,12 @@ public class MockVirtualFile extends VirtualFile {
MockVirtualFile file = (MockVirtualFile)o;
- if (myPath != null ? !myPath.equals(file.myPath) : file.myPath != null) return false;
-
- return true;
+ return myPath.equals(file.myPath);
}
@Override
public int hashCode() {
- return myPath != null ? myPath.hashCode() : 0;
+ return myPath.hashCode();
}
}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java
index 7a6a0cf04361..1d1540910539 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java
@@ -21,13 +21,14 @@ import com.intellij.openapi.project.PossiblyDumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.SmartList;
import org.intellij.lang.annotations.JdkConstants;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.ArrayList;
+import java.util.List;
/**
* Represents an entity that has a state, a presentation and can be performed.
@@ -143,9 +144,10 @@ public abstract class AnAction implements PossiblyDumbAware {
public final void registerCustomShortcutSet(@NotNull ShortcutSet shortcutSet, @Nullable JComponent component){
myShortcutSet = shortcutSet;
if (component != null){
- @SuppressWarnings("unchecked") ArrayList<AnAction> actionList = (ArrayList<AnAction>)component.getClientProperty(ourClientProperty);
+ @SuppressWarnings("unchecked")
+ List<AnAction> actionList = (List<AnAction>)component.getClientProperty(ourClientProperty);
if (actionList == null){
- actionList = new ArrayList<AnAction>(1);
+ actionList = new SmartList<AnAction>();
component.putClientProperty(ourClientProperty, actionList);
}
if (!actionList.contains(this)){
@@ -170,7 +172,8 @@ public abstract class AnAction implements PossiblyDumbAware {
public final void unregisterCustomShortcutSet(JComponent component){
if (component != null){
- @SuppressWarnings("unchecked") ArrayList<AnAction> actionList = (ArrayList<AnAction>)component.getClientProperty(ourClientProperty);
+ @SuppressWarnings("unchecked")
+ List<AnAction> actionList = (List<AnAction>)component.getClientProperty(ourClientProperty);
if (actionList != null){
actionList.remove(this);
}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java
index 3648e477da83..43b5e75e08df 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java
@@ -202,6 +202,8 @@ public interface Caret extends UserDataHolderEx, Disposable {
* Selects target range providing information about visual boundary of selection end.
* <p/>
* That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
+ * <p/>
+ * Also, in column mode this method allows to create selection spanning virtual space after the line end.
*
* @param startOffset start selection offset
* @param endPosition end visual position of the text range to select (<code>null</code> argument means that
@@ -214,6 +216,8 @@ public interface Caret extends UserDataHolderEx, Disposable {
* Selects target range based on its visual boundaries.
* <p/>
* That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
+ * <p/>
+ * Also, in column mode this method allows to create selection spanning virtual space after the line end.
*
* @param startPosition start visual position of the text range to select (<code>null</code> argument means that
* no specific visual position should be used)
@@ -249,8 +253,8 @@ public interface Caret extends UserDataHolderEx, Disposable {
* selection will be set for the new caret.
*
* @param above if <code>true</code>, new caret will be created at the previous line, if <code>false</code> - on the next line
- * @return newly created caret instance, or null if the caret cannot be created because it already exists at the new location or caret
- * model doesn't support multiple carets.
+ * @return newly created caret instance, or <code>null</code> if the caret cannot be created because it already exists at the new location
+ * or caret model doesn't support multiple carets.
*/
@Nullable
Caret clone(boolean above);
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 17ddb3f820b3..1d26b77128b3 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
@@ -17,7 +17,6 @@ package com.intellij.openapi.editor;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.editor.markup.TextAttributes;
-import com.intellij.openapi.util.Segment;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -130,14 +129,14 @@ public interface CaretModel {
int getOffset();
/**
- * Adds a listener for receiving notifications about caret movement.
+ * Adds a listener for receiving notifications about caret movement and caret addition/removal
*
* @param listener the listener instance.
*/
void addCaretListener(@NotNull CaretListener listener);
/**
- * Removes a listener for receiving notifications about caret movement.
+ * Removes a listener for receiving notifications about caret movement and caret addition/removal
*
* @param listener the listener instance.
*/
@@ -182,6 +181,11 @@ public interface CaretModel {
Caret getPrimaryCaret();
/**
+ * Returns number of carets currently existing in the document
+ */
+ int getCaretCount();
+
+ /**
* Returns all carets currently existing in the document, ordered by their position in the document.
*/
@NotNull
@@ -214,14 +218,14 @@ public interface CaretModel {
void removeSecondaryCarets();
/**
- * Sets the number of carets, their positions and selection ranges according to the provided parameters. Null values in any of the
- * collections will mean that corresponding caret's position and/or selection won't be changed.
+ * Sets the number of carets, their positions and selection ranges according to the provided data. Null values for caret position or
+ * selection boundaries will mean that corresponding caret's position and/or selection won't be changed.
* <p>
* If multiple carets are not supported, the behaviour is unspecified.
*
* @see #supportsMultipleCarets()
*/
- void setCaretsAndSelections(@NotNull List<LogicalPosition> caretPositions, @NotNull List<? extends Segment> selections);
+ void setCaretsAndSelections(@NotNull List<CaretState> caretStates);
/**
* Executes the given task for each existing caret. Carets are iterated in their position order. Set of carets to iterate over is
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretState.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretState.java
new file mode 100644
index 000000000000..d7588f14d194
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretState.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.intellij.openapi.editor;
+
+import org.jetbrains.annotations.Nullable;
+
+public class CaretState {
+ private final LogicalPosition caretPosition;
+ private final LogicalPosition selectionStart;
+ private final LogicalPosition selectionEnd;
+
+ public CaretState(@Nullable LogicalPosition position, @Nullable LogicalPosition start, @Nullable LogicalPosition end) {
+ caretPosition = position;
+ selectionStart = start;
+ selectionEnd = end;
+ }
+
+ @Nullable
+ public LogicalPosition getCaretPosition(){
+ return caretPosition;
+ }
+
+ @Nullable
+ public LogicalPosition getSelectionStart() {
+ return selectionStart;
+ }
+
+ @Nullable
+ public LogicalPosition getSelectionEnd() {
+ return selectionEnd;
+ }
+
+ @Override
+ public String toString() {
+ return "CaretState{" +
+ "caretPosition=" + caretPosition +
+ ", selectionStart=" + selectionStart +
+ ", selectionEnd=" + selectionEnd +
+ '}';
+ }
+}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/event/MultipleCaretListener.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/event/CaretAdapter.java
index 0c225cf922a6..86b2bac7f4fd 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/event/MultipleCaretListener.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/event/CaretAdapter.java
@@ -15,21 +15,16 @@
*/
package com.intellij.openapi.editor.event;
-/**
- * In addition to caret movement event received by CaretListener instances, these listeners will also get caret creation/destroying events.
- *
- * @see CaretListener
- * @see com.intellij.openapi.editor.CaretModel#addCaretListener(CaretListener)
- * @see EditorEventMulticaster#addCaretListener(CaretListener)
- */
-public interface MultipleCaretListener extends CaretListener {
- /**
- * Called when a new caret was added to the document.
- */
- void caretAdded(CaretEvent e);
+public abstract class CaretAdapter implements CaretListener {
+ @Override
+ public void caretPositionChanged(CaretEvent e) {
+ }
+
+ @Override
+ public void caretAdded(CaretEvent e) {
+ }
- /**
- * Called when a caret was removed from the document.
- */
- void caretRemoved(CaretEvent e);
+ @Override
+ public void caretRemoved(CaretEvent e) {
+ }
}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/event/CaretListener.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/event/CaretListener.java
index d99649c97d2f..fe73fc1a4cc5 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/event/CaretListener.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/event/CaretListener.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,7 +18,7 @@ package com.intellij.openapi.editor.event;
import java.util.EventListener;
/**
- * Allows to receive notifications about caret movement.
+ * Allows to receive notifications about caret movement, and caret additions/removal
*
* @see com.intellij.openapi.editor.CaretModel#addCaretListener(CaretListener)
* @see EditorEventMulticaster#addCaretListener(CaretListener)
@@ -30,4 +30,14 @@ public interface CaretListener extends EventListener {
* @param e the event containing information about the caret movement.
*/
void caretPositionChanged(CaretEvent e);
+
+ /**
+ * Called when a new caret was added to the document.
+ */
+ void caretAdded(CaretEvent e);
+
+ /**
+ * Called when a caret was removed from the document.
+ */
+ void caretRemoved(CaretEvent e);
}
diff --git a/platform/editor-ui-ex/src/com/intellij/injected/editor/MarkupModelWindow.java b/platform/editor-ui-ex/src/com/intellij/injected/editor/MarkupModelWindow.java
index b11ff743642e..9fd72279c4f2 100644
--- a/platform/editor-ui-ex/src/com/intellij/injected/editor/MarkupModelWindow.java
+++ b/platform/editor-ui-ex/src/com/intellij/injected/editor/MarkupModelWindow.java
@@ -110,7 +110,7 @@ public class MarkupModelWindow extends UserDataHolderBase implements MarkupModel
}
@Override
- public RangeHighlighter addPersistentLineHighlighter(final int line, final int layer, final TextAttributes textAttributes) {
+ public RangeHighlighterEx addPersistentLineHighlighter(final int line, final int layer, final TextAttributes textAttributes) {
int hostLine = myDocument.injectedToHostLine(line);
return myHostModel.addPersistentLineHighlighter(hostLine, layer, textAttributes);
}
diff --git a/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/MarkupModelEx.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/MarkupModelEx.java
index 284ef90e2007..28d8cb447d7c 100644
--- a/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/MarkupModelEx.java
+++ b/platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/MarkupModelEx.java
@@ -33,7 +33,7 @@ public interface MarkupModelEx extends MarkupModel {
void dispose();
@Nullable
- RangeHighlighter addPersistentLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes);
+ RangeHighlighterEx addPersistentLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes);
void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged);
diff --git a/platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/EmptyMarkupModel.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/EmptyMarkupModel.java
index d9e5c4bd51bd..a3ac344e23bf 100644
--- a/platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/EmptyMarkupModel.java
+++ b/platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/EmptyMarkupModel.java
@@ -109,7 +109,7 @@ public class EmptyMarkupModel implements MarkupModelEx {
}
@Override
- public RangeHighlighter addPersistentLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes) {
+ public RangeHighlighterEx addPersistentLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes) {
return null;
}
diff --git a/platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java
index 50a9922d1bcb..5724189b0110 100644
--- a/platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java
+++ b/platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java
@@ -76,13 +76,13 @@ public class MarkupModelImpl extends UserDataHolderBase implements MarkupModelEx
@Override
@Nullable
- public RangeHighlighter addPersistentLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes) {
+ public RangeHighlighterEx addPersistentLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes) {
if (isNotValidLine(lineNumber)) {
return null;
}
int offset = getFirstNonSpaceCharOffset(getDocument(), lineNumber);
- return addRangeHighlighter(PersistentRangeHighlighterImpl.create(this, offset, layer, HighlighterTargetArea.LINES_IN_RANGE, null, false), null);
+ return addRangeHighlighter(PersistentRangeHighlighterImpl.create(this, offset, layer, HighlighterTargetArea.LINES_IN_RANGE, textAttributes, false), null);
}
private boolean isNotValidLine(int lineNumber) {
diff --git a/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java
index dca89ac7bf8a..08eab82f0dcf 100644
--- a/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java
+++ b/platform/editor-ui-ex/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.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,13 +70,13 @@ public class TodoIndex extends FileBasedIndexExtension<TodoIndexEntry, Integer>
}
@Override
- public void save(final DataOutput out, final TodoIndexEntry value) throws IOException {
+ public void save(@NotNull final DataOutput out, final TodoIndexEntry value) throws IOException {
out.writeUTF(value.pattern);
out.writeBoolean(value.caseSensitive);
}
@Override
- public TodoIndexEntry read(final DataInput in) throws IOException {
+ public TodoIndexEntry read(@NotNull final DataInput in) throws IOException {
final String pattern = in.readUTF();
final boolean caseSensitive = in.readBoolean();
return new TodoIndexEntry(pattern, caseSensitive);
@@ -106,7 +106,7 @@ public class TodoIndex extends FileBasedIndexExtension<TodoIndexEntry, Integer>
private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() {
@Override
- public boolean acceptInput(final VirtualFile file) {
+ public boolean acceptInput(@NotNull final VirtualFile file) {
if (!file.isInLocalFileSystem()) {
return false; // do not index TODOs in library sources
}
@@ -147,16 +147,19 @@ public class TodoIndex extends FileBasedIndexExtension<TodoIndexEntry, Integer>
return myIndexer;
}
+ @NotNull
@Override
public KeyDescriptor<TodoIndexEntry> getKeyDescriptor() {
return myKeyDescriptor;
}
+ @NotNull
@Override
public DataExternalizer<Integer> getValueExternalizer() {
return myValueExternalizer;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return myInputFilter;
diff --git a/platform/icons/src/nodes/pluginJB.png b/platform/icons/src/nodes/pluginJB.png
new file mode 100644
index 000000000000..54b036124bf0
--- /dev/null
+++ b/platform/icons/src/nodes/pluginJB.png
Binary files differ
diff --git a/platform/icons/src/nodes/pluginJB@2x.png b/platform/icons/src/nodes/pluginJB@2x.png
new file mode 100644
index 000000000000..dbaac8fe84f1
--- /dev/null
+++ b/platform/icons/src/nodes/pluginJB@2x.png
Binary files differ
diff --git a/platform/icons/src/nodes/pluginJB@2x_dark.png b/platform/icons/src/nodes/pluginJB@2x_dark.png
new file mode 100644
index 000000000000..6af31910d8c6
--- /dev/null
+++ b/platform/icons/src/nodes/pluginJB@2x_dark.png
Binary files differ
diff --git a/platform/icons/src/nodes/pluginJB_dark.png b/platform/icons/src/nodes/pluginJB_dark.png
new file mode 100644
index 000000000000..7325cf713fa9
--- /dev/null
+++ b/platform/icons/src/nodes/pluginJB_dark.png
Binary files differ
diff --git a/platform/icons/src/nodes/pluginRestart.png b/platform/icons/src/nodes/pluginRestart.png
new file mode 100644
index 000000000000..a47d933dbeb1
--- /dev/null
+++ b/platform/icons/src/nodes/pluginRestart.png
Binary files differ
diff --git a/platform/icons/src/nodes/pluginRestart@2x.png b/platform/icons/src/nodes/pluginRestart@2x.png
new file mode 100644
index 000000000000..3c9e05c8ea49
--- /dev/null
+++ b/platform/icons/src/nodes/pluginRestart@2x.png
Binary files differ
diff --git a/platform/icons/src/nodes/pluginRestart@2x_dark.png b/platform/icons/src/nodes/pluginRestart@2x_dark.png
new file mode 100644
index 000000000000..4c4439c08ad6
--- /dev/null
+++ b/platform/icons/src/nodes/pluginRestart@2x_dark.png
Binary files differ
diff --git a/platform/icons/src/nodes/pluginRestart_dark.png b/platform/icons/src/nodes/pluginRestart_dark.png
new file mode 100644
index 000000000000..c0cc12aa9e9c
--- /dev/null
+++ b/platform/icons/src/nodes/pluginRestart_dark.png
Binary files differ
diff --git a/platform/icons/src/nodes/pluginUpdate.png b/platform/icons/src/nodes/pluginUpdate.png
new file mode 100644
index 000000000000..62f0a4fbfeac
--- /dev/null
+++ b/platform/icons/src/nodes/pluginUpdate.png
Binary files differ
diff --git a/platform/icons/src/nodes/pluginUpdate@2x.png b/platform/icons/src/nodes/pluginUpdate@2x.png
new file mode 100644
index 000000000000..b0b65f1f314c
--- /dev/null
+++ b/platform/icons/src/nodes/pluginUpdate@2x.png
Binary files differ
diff --git a/platform/icons/src/nodes/pluginUpdate@2x_dark.png b/platform/icons/src/nodes/pluginUpdate@2x_dark.png
new file mode 100644
index 000000000000..8801cf28dcd3
--- /dev/null
+++ b/platform/icons/src/nodes/pluginUpdate@2x_dark.png
Binary files differ
diff --git a/platform/icons/src/nodes/pluginUpdate_dark.png b/platform/icons/src/nodes/pluginUpdate_dark.png
new file mode 100644
index 000000000000..aa051df7a17c
--- /dev/null
+++ b/platform/icons/src/nodes/pluginUpdate_dark.png
Binary files differ
diff --git a/platform/indexing-api/src/com/intellij/util/indexing/DefaultFileTypeSpecificInputFilter.java b/platform/indexing-api/src/com/intellij/util/indexing/DefaultFileTypeSpecificInputFilter.java
index 6273968c678f..903c5c4992be 100644
--- a/platform/indexing-api/src/com/intellij/util/indexing/DefaultFileTypeSpecificInputFilter.java
+++ b/platform/indexing-api/src/com/intellij/util/indexing/DefaultFileTypeSpecificInputFilter.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,7 +32,7 @@ public class DefaultFileTypeSpecificInputFilter implements FileBasedIndex.FileTy
}
@Override
- public boolean acceptInput(VirtualFile file) {
+ public boolean acceptInput(@NotNull VirtualFile file) {
return true;
}
}
diff --git a/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java b/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java
index 3cdb853b6d95..6628f3c9225e 100644
--- a/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java
+++ b/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.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.
@@ -137,7 +137,7 @@ public abstract class FileBasedIndex implements BaseComponent {
* @param project it is guaranteed to return data which is up-to-date withing the project
* Keys obtained from the files which do not belong to the project specified may not be up-to-date or even exist
*/
- public abstract <K> boolean processAllKeys(@NotNull ID<K, ?> indexId, Processor<K> processor, @Nullable Project project);
+ public abstract <K> boolean processAllKeys(@NotNull ID<K, ?> indexId, @NotNull Processor<K> processor, @Nullable Project project);
public <K> boolean processAllKeys(@NotNull ID<K, ?> indexId, @NotNull Processor<K> processor, @NotNull GlobalSearchScope scope, @Nullable IdFilter idFilter) {
return processAllKeys(indexId, processor, scope.getProject());
@@ -156,7 +156,7 @@ public abstract class FileBasedIndex implements BaseComponent {
* Author: dmitrylomov
*/
public interface InputFilter {
- boolean acceptInput(VirtualFile file);
+ boolean acceptInput(@NotNull VirtualFile file);
}
public interface FileTypeSpecificInputFilter extends InputFilter {
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 91d9470bbc61..dc6091964163 100644
--- a/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java
+++ b/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.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,11 +39,14 @@ public abstract class FileBasedIndexExtension<K, V> {
@NotNull
public abstract DataIndexer<K, V, FileContent> getIndexer();
-
+
+ @NotNull
public abstract KeyDescriptor<K> getKeyDescriptor();
-
+
+ @NotNull
public abstract DataExternalizer<V> getValueExternalizer();
-
+
+ @NotNull
public abstract FileBasedIndex.InputFilter getInputFilter();
public abstract boolean dependsOnFileContent();
diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/ModuleScopeProviderImpl.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/ModuleScopeProviderImpl.java
index f90fe7876987..052c73022d53 100644
--- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/ModuleScopeProviderImpl.java
+++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/ModuleScopeProviderImpl.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,8 +31,7 @@ public class ModuleScopeProviderImpl implements ModuleScopeProvider {
private GlobalSearchScope myModuleWithDependentsScope;
private GlobalSearchScope myModuleTestsWithDependentsScope;
-
- public ModuleScopeProviderImpl(Module module) {
+ public ModuleScopeProviderImpl(@NotNull Module module) {
myModule = module;
}
@@ -47,53 +46,72 @@ public class ModuleScopeProviderImpl implements ModuleScopeProvider {
}
+ @Override
+ @NotNull
public GlobalSearchScope getModuleScope() {
return getCachedScope(ModuleWithDependenciesScope.COMPILE | ModuleWithDependenciesScope.TESTS);
}
+ @NotNull
@Override
public GlobalSearchScope getModuleScope(boolean includeTests) {
return getCachedScope(ModuleWithDependenciesScope.COMPILE | (includeTests ? ModuleWithDependenciesScope.TESTS : 0));
}
+ @Override
+ @NotNull
public GlobalSearchScope getModuleWithLibrariesScope() {
return getCachedScope(ModuleWithDependenciesScope.COMPILE | ModuleWithDependenciesScope.TESTS | ModuleWithDependenciesScope.LIBRARIES);
}
+ @Override
+ @NotNull
public GlobalSearchScope getModuleWithDependenciesScope() {
return getCachedScope(ModuleWithDependenciesScope.COMPILE | ModuleWithDependenciesScope.TESTS | ModuleWithDependenciesScope.MODULES);
}
+ @NotNull
@Override
public GlobalSearchScope getModuleContentScope() {
return getCachedScope(ModuleWithDependenciesScope.CONTENT);
}
+ @NotNull
@Override
public GlobalSearchScope getModuleContentWithDependenciesScope() {
return getCachedScope(ModuleWithDependenciesScope.CONTENT | ModuleWithDependenciesScope.MODULES);
}
+ @Override
+ @NotNull
public GlobalSearchScope getModuleWithDependenciesAndLibrariesScope(boolean includeTests) {
return getCachedScope(ModuleWithDependenciesScope.COMPILE |
ModuleWithDependenciesScope.MODULES |
ModuleWithDependenciesScope.LIBRARIES | (includeTests ? ModuleWithDependenciesScope.TESTS : 0));
}
+ @Override
+ @NotNull
public GlobalSearchScope getModuleWithDependentsScope() {
- if (myModuleWithDependentsScope == null) {
- myModuleWithDependentsScope = new ModuleWithDependentsScope(myModule, false);
+ GlobalSearchScope scope = myModuleWithDependentsScope;
+ if (scope == null) {
+ myModuleWithDependentsScope = scope = new ModuleWithDependentsScope(myModule, false);
}
- return myModuleWithDependentsScope;
+ return scope;
}
+ @Override
+ @NotNull
public GlobalSearchScope getModuleTestsWithDependentsScope() {
- if (myModuleTestsWithDependentsScope == null) {
- myModuleTestsWithDependentsScope = new ModuleWithDependentsScope(myModule, true);
+ GlobalSearchScope scope = myModuleTestsWithDependentsScope;
+ if (scope == null) {
+ myModuleTestsWithDependentsScope = scope = new ModuleWithDependentsScope(myModule, true);
}
- return myModuleTestsWithDependentsScope;
+ return scope;
}
+ @Override
+ @NotNull
public GlobalSearchScope getModuleRuntimeScope(boolean includeTests) {
return getCachedScope(
ModuleWithDependenciesScope.MODULES | ModuleWithDependenciesScope.LIBRARIES | (includeTests ? ModuleWithDependenciesScope.TESTS : 0));
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 0839c80eeb23..477a04f1d549 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
@@ -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.
@@ -54,7 +54,7 @@ public class ModuleWithDependenciesScope extends GlobalSearchScope {
private final Set<Module> myModules;
private final TObjectIntHashMap<VirtualFile> myRoots = new TObjectIntHashMap<VirtualFile>();
- public ModuleWithDependenciesScope(Module module, @ScopeConstant int options) {
+ public ModuleWithDependenciesScope(@NotNull Module module, @ScopeConstant int options) {
super(module.getProject());
myModule = module;
myOptions = options;
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java
index 4ad94f5865fc..3e96882ddea1 100644
--- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.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,19 +43,19 @@ public class IdIndex extends FileBasedIndexExtension<IdIndexEntry, Integer> {
private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() {
@Override
- public boolean acceptInput(final VirtualFile file) {
+ public boolean acceptInput(@NotNull final VirtualFile file) {
return isIndexable(file.getFileType());
}
};
private final DataExternalizer<Integer> myValueExternalizer = new DataExternalizer<Integer>() {
@Override
- public void save(final DataOutput out, final Integer value) throws IOException {
+ public void save(@NotNull final DataOutput out, final Integer value) throws IOException {
out.writeByte(value.intValue());
}
@Override
- public Integer read(final DataInput in) throws IOException {
+ public Integer read(@NotNull final DataInput in) throws IOException {
return Integer.valueOf(in.readByte());
}
};
@@ -107,16 +107,19 @@ public class IdIndex extends FileBasedIndexExtension<IdIndexEntry, Integer> {
return myIndexer;
}
+ @NotNull
@Override
public DataExternalizer<Integer> getValueExternalizer() {
return myValueExternalizer;
}
+ @NotNull
@Override
public KeyDescriptor<IdIndexEntry> getKeyDescriptor() {
return myKeyDescriptor;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return myInputFilter;
diff --git a/platform/indexing-impl/src/com/intellij/psi/search/FileTypeIndex.java b/platform/indexing-impl/src/com/intellij/psi/search/FileTypeIndex.java
index b0a8673ec6ed..061100b77470 100644
--- a/platform/indexing-impl/src/com/intellij/psi/search/FileTypeIndex.java
+++ b/platform/indexing-impl/src/com/intellij/psi/search/FileTypeIndex.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.search;
import com.intellij.openapi.fileTypes.FileType;
@@ -47,11 +62,13 @@ public class FileTypeIndex extends ScalarIndexExtension<FileType>
return this;
}
+ @NotNull
@Override
public KeyDescriptor<FileType> getKeyDescriptor() {
return this;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return this;
@@ -73,17 +90,17 @@ public class FileTypeIndex extends ScalarIndexExtension<FileType>
}
@Override
- public boolean acceptInput(VirtualFile file) {
+ public boolean acceptInput(@NotNull VirtualFile file) {
return !file.isDirectory();
}
@Override
- public void save(DataOutput out, FileType value) throws IOException {
+ public void save(@NotNull DataOutput out, FileType value) throws IOException {
myEnumeratorStringDescriptor.save(out, value.getName());
}
@Override
- public FileType read(DataInput in) throws IOException {
+ public FileType read(@NotNull DataInput in) throws IOException {
String read = myEnumeratorStringDescriptor.read(in);
return myFileTypeManager.findFileTypeByName(read);
}
diff --git a/platform/indexing-impl/src/com/intellij/psi/search/FilenameIndex.java b/platform/indexing-impl/src/com/intellij/psi/search/FilenameIndex.java
index 7c42954efe82..0e95aefcc0bb 100644
--- a/platform/indexing-impl/src/com/intellij/psi/search/FilenameIndex.java
+++ b/platform/indexing-impl/src/com/intellij/psi/search/FilenameIndex.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.
@@ -54,11 +54,13 @@ public class FilenameIndex extends ScalarIndexExtension<String> {
return myDataIndexer;
}
+ @NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return myKeyDescriptor;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return myInputFilter;
@@ -156,7 +158,7 @@ public class FilenameIndex extends ScalarIndexExtension<String> {
private static class MyInputFilter implements FileBasedIndex.InputFilter {
@Override
- public boolean acceptInput(final VirtualFile file) {
+ public boolean acceptInput(@NotNull final VirtualFile file) {
return true;
}
}
diff --git a/platform/indexing-impl/src/com/intellij/util/indexing/ScalarIndexExtension.java b/platform/indexing-impl/src/com/intellij/util/indexing/ScalarIndexExtension.java
index df1550082dd7..38321417c29e 100644
--- a/platform/indexing-impl/src/com/intellij/util/indexing/ScalarIndexExtension.java
+++ b/platform/indexing-impl/src/com/intellij/util/indexing/ScalarIndexExtension.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.util.indexing;
import com.intellij.util.io.DataExternalizer;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.DataInput;
@@ -31,6 +32,7 @@ public abstract class ScalarIndexExtension<K> extends FileBasedIndexExtension<K,
public static final DataExternalizer<Void> VOID_DATA_EXTERNALIZER = new VoidDataExternalizer();
+ @NotNull
@Override
public final DataExternalizer<Void> getValueExternalizer() {
return VOID_DATA_EXTERNALIZER;
@@ -39,12 +41,12 @@ public abstract class ScalarIndexExtension<K> extends FileBasedIndexExtension<K,
private static class VoidDataExternalizer implements DataExternalizer<Void> {
@Override
- public void save(final DataOutput out, final Void value) throws IOException {
+ public void save(@NotNull final DataOutput out, final Void value) throws IOException {
}
@Override
@Nullable
- public Void read(final DataInput in) throws IOException {
+ public Void read(@NotNull final DataInput in) throws IOException {
return null;
}
}
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 128d7d40d4fe..1e111b2d01de 100644
--- a/platform/indexing-impl/src/com/intellij/util/indexing/SingleEntryFileBasedIndexExtension.java
+++ b/platform/indexing-impl/src/com/intellij/util/indexing/SingleEntryFileBasedIndexExtension.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 org.jetbrains.annotations.NotNull;
* Date: Feb 18, 2009
*/
public abstract class SingleEntryFileBasedIndexExtension<V> extends FileBasedIndexExtension<Integer, V>{
+ @NotNull
@Override
public final KeyDescriptor<Integer> getKeyDescriptor() {
return EnumeratorIntegerDescriptor.INSTANCE;
diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/ClickNavigator.java b/platform/lang-impl/src/com/intellij/application/options/colors/ClickNavigator.java
index 464bf038d986..df10c20fe536 100644
--- a/platform/lang-impl/src/com/intellij/application/options/colors/ClickNavigator.java
+++ b/platform/lang-impl/src/com/intellij/application/options/colors/ClickNavigator.java
@@ -1,6 +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 +24,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.HighlighterColors;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.editor.event.CaretAdapter;
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.editor.ex.EditorEx;
@@ -56,7 +56,7 @@ public class ClickNavigator {
}
});
- CaretListener listener = new CaretListener() {
+ CaretListener listener = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
setSelectedItem(HighlighterColors.TEXT.getExternalName(), true);
@@ -98,7 +98,7 @@ public class ClickNavigator {
final boolean isBackgroundImportant) {
addMouseMotionListener(view, highlighter, data, isBackgroundImportant);
- CaretListener listener = new CaretListener() {
+ CaretListener listener = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
navigate(view, true, e.getNewPosition(), highlighter, data, isBackgroundImportant);
diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/SimpleEditorPreview.java b/platform/lang-impl/src/com/intellij/application/options/colors/SimpleEditorPreview.java
index 6daa2db58134..e7e92ca98401 100644
--- a/platform/lang-impl/src/com/intellij/application/options/colors/SimpleEditorPreview.java
+++ b/platform/lang-impl/src/com/intellij/application/options/colors/SimpleEditorPreview.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.
@@ -23,6 +23,7 @@ import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.editor.event.CaretAdapter;
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.editor.ex.EditorEx;
@@ -80,7 +81,7 @@ public class SimpleEditorPreview implements PreviewPanel{
if (navigatable) {
addMouseMotionListener(myEditor, page.getHighlighter(), myHighlightData, false);
- CaretListener listener = new CaretListener() {
+ CaretListener listener = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
navigate(myEditor, true, e.getNewPosition(), page.getHighlighter(), myHighlightData, false);
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 a721c6f04aaa..392e35ac5941 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
@@ -622,20 +622,26 @@ public class CodeCompletionHandlerBase {
marker.dispose();
}
- } else {
- final Ref<CompletionAssertions.WatchingInsertionContext> contextRef = new Ref<CompletionAssertions.WatchingInsertionContext>();
- final Caret primaryCaret = editor.getCaretModel().getPrimaryCaret();
+ } else if (editor.getCaretModel().supportsMultipleCarets()) {
+ final List<CompletionAssertions.WatchingInsertionContext> contexts = new ArrayList<CompletionAssertions.WatchingInsertionContext>();
editor.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);
- if (caret == primaryCaret) {
- contextRef.set(currentContext);
- }
+ contexts.add(currentContext);
}
});
- context = contextRef.get();
+ context = contexts.get(contexts.size() - 1);
+ if (context.shouldAddCompletionChar() && context.getCompletionChar() != Lookup.COMPLETE_STATEMENT_SELECT_CHAR) {
+ DataContext dataContext = DataManager.getInstance().getDataContext(editor.getContentComponent());
+ EditorActionManager.getInstance().getTypedAction().getHandler().execute(editor, completionChar, dataContext);
+ }
+ for (CompletionAssertions.WatchingInsertionContext insertionContext : contexts) {
+ insertionContext.stopWatching();
+ }
+ } else {
+ context = insertItem(indicator, item, completionChar, items, update, editor, caretOffset, idEndOffset);
}
return context;
}
@@ -719,7 +725,9 @@ public class CodeCompletionHandlerBase {
if (context.shouldAddCompletionChar()) {
addCompletionChar(project, context, item, editor, indicator, completionChar);
}
- context.stopWatching();
+ if (!editor.getCaretModel().supportsMultipleCarets()) { // done later, outside of this method
+ context.stopWatching();
+ }
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
});
@@ -747,7 +755,7 @@ public class CodeCompletionHandlerBase {
}
}
}
- else {
+ else if (!editor.getCaretModel().supportsMultipleCarets()) { // this will be done outside of runForEach caret context
DataContext dataContext = DataManager.getInstance().getDataContext(editor.getContentComponent());
EditorActionManager.getInstance().getTypedAction().getHandler().execute(editor, completionChar, dataContext);
}
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 6ba44fde4fdc..d135e19f9e52 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.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.
@@ -253,7 +253,7 @@ public abstract class CompletionPhase implements Disposable {
CompletionServiceImpl.setCompletionPhase(NoCompletion);
}
};
- final CaretListener caretListener = new CaretListener() {
+ final CaretListener caretListener = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
CompletionServiceImpl.setCompletionPhase(NoCompletion);
@@ -341,7 +341,7 @@ public abstract class CompletionPhase implements Disposable {
}
};
- caretListener = new CaretListener() {
+ caretListener = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
if (!TypedAction.isTypedActionInProgress()) {
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 d20e48149b1c..b33a029cc7c3 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
@@ -176,7 +176,7 @@ public class DaemonListeners implements Disposable {
}
}, this);
- eventMulticaster.addCaretListener(new CaretListener() {
+ eventMulticaster.addCaretListener(new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
final Editor editor = e.getEditor();
@@ -184,17 +184,17 @@ public class DaemonListeners implements Disposable {
!worthBothering(editor.getDocument(), editor.getProject())) {
return; //no need to stop daemon if something happened in the console
}
-
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- if (!editor.getComponent().isShowing() && !application.isUnitTestMode() ||
- myProject.isDisposed()) {
- return;
+ if (!application.isUnitTestMode()) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ if (!editor.getComponent().isShowing() || myProject.isDisposed()) {
+ return;
+ }
+ myDaemonCodeAnalyzer.hideLastIntentionHint();
}
- myDaemonCodeAnalyzer.hideLastIntentionHint();
- }
- }, ModalityState.current());
+ }, ModalityState.current());
+ }
}
}, this);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java
index 89e8b55f9b4c..199f66732699 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.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.
@@ -354,7 +354,7 @@ public class QuickDocOnMouseOverManager {
}
}
- private class MyCaretListener implements CaretListener {
+ private class MyCaretListener extends CaretAdapter {
@Override
public void caretPositionChanged(CaretEvent e) {
allowUpdateFromContext(true);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java
index 9c15f4ffde8a..0296e8e139dc 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java
@@ -90,7 +90,7 @@ public class PasteHandler extends EditorActionHandler implements EditorTextInser
final Project project = editor.getProject();
if (project == null || editor.isColumnMode() || editor.getSelectionModel().hasBlockSelection()
- || editor.getCaretModel().getAllCarets().size() > 1) {
+ || editor.getCaretModel().getCaretCount() > 1) {
if (myOriginalHandler != null) {
myOriginalHandler.execute(editor, context);
}
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 216227d7744c..259fe9766fb1 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java
@@ -135,10 +135,7 @@ public class TypedHandler extends TypedActionHandlerBase {
Project project = CommonDataKeys.PROJECT.getData(dataContext);
PsiFile file;
- if (project == null
- || editor.isColumnMode()
- || editor.getCaretModel().getAllCarets().size() > 1
- || (file = PsiUtilBase.getPsiFileInEditor(editor, project)) == null) {
+ if (project == null || editor.isColumnMode() || (file = PsiUtilBase.getPsiFileInEditor(editor, project)) == null) {
if (myOriginalHandler != null){
myOriginalHandler.execute(editor, charTyped, dataContext);
}
@@ -174,13 +171,13 @@ public class TypedHandler extends TypedActionHandlerBase {
}
if (!editor.isInsertMode()){
- myOriginalHandler.execute(originalEditor, charTyped, dataContext);
+ if (myOriginalHandler != null) {
+ myOriginalHandler.execute(originalEditor, charTyped, dataContext);
+ }
return;
}
- if (editor.getSelectionModel().hasSelection()){
- EditorModificationUtil.deleteSelectedText(editor);
- }
+ EditorModificationUtil.deleteSelectedTextForAllCarets(editor);
FileType fileType = getFileType(file, editor);
@@ -194,7 +191,7 @@ public class TypedHandler extends TypedActionHandlerBase {
}
}
- if (!editor.getSelectionModel().hasBlockSelection()) {
+ if (!editor.getSelectionModel().hasBlockSelection() && editor.getCaretModel().getCaretCount() == 1) {
if (')' == charTyped || ']' == charTyped || '}' == charTyped) {
if (FileTypes.PLAIN_TEXT != fileType) {
if (handleRParen(editor, fileType, charTyped)) return;
@@ -206,12 +203,14 @@ public class TypedHandler extends TypedActionHandlerBase {
}
long modificationStampBeforeTyping = editor.getDocument().getModificationStamp();
- myOriginalHandler.execute(originalEditor, charTyped, dataContext);
+ if (myOriginalHandler != null) {
+ myOriginalHandler.execute(originalEditor, charTyped, dataContext);
+ }
AutoHardWrapHandler.getInstance().wrapLineIfNecessary(editor, dataContext, modificationStampBeforeTyping);
if (('(' == charTyped || '[' == charTyped || '{' == charTyped) &&
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET &&
- !editor.getSelectionModel().hasBlockSelection() && fileType != FileTypes.PLAIN_TEXT) {
+ !editor.getSelectionModel().hasBlockSelection() && editor.getCaretModel().getCaretCount() == 1 && fileType != FileTypes.PLAIN_TEXT) {
handleAfterLParen(editor, fileType, charTyped);
}
else if ('}' == charTyped) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/BaseIndentEnterHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/BaseIndentEnterHandler.java
index 48c1dfbef792..524a2b2f286a 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/BaseIndentEnterHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/BaseIndentEnterHandler.java
@@ -83,15 +83,7 @@ public class BaseIndentEnterHandler extends EnterHandlerDelegateAdapter {
myWorksWithFormatter = worksWithFormatter;
}
- @Override
- public Result preprocessEnter(
- @NotNull final PsiFile file,
- @NotNull final Editor editor,
- @NotNull final Ref<Integer> caretOffset,
- @NotNull final Ref<Integer> caretAdvance,
- @NotNull final DataContext dataContext,
- final EditorActionHandler originalHandler)
- {
+ protected Result shouldSkipWithResult(@NotNull final PsiFile file, @NotNull final Editor editor, @NotNull final DataContext dataContext) {
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (project == null) {
return Result.Continue;
@@ -119,7 +111,25 @@ public class BaseIndentEnterHandler extends EnterHandlerDelegateAdapter {
if (caret <= 0) {
return Result.Continue;
}
+ return null;
+ }
+
+ @Override
+ public Result preprocessEnter(
+ @NotNull final PsiFile file,
+ @NotNull final Editor editor,
+ @NotNull final Ref<Integer> caretOffset,
+ @NotNull final Ref<Integer> caretAdvance,
+ @NotNull final DataContext dataContext,
+ final EditorActionHandler originalHandler)
+ {
+ Result res = shouldSkipWithResult(file, editor, dataContext);
+ if (res != null) {
+ return res;
+ }
+ final Document document = editor.getDocument();
+ int caret = editor.getCaretModel().getOffset();
final int lineNumber = document.getLineNumber(caret);
final int lineStartOffset = document.getLineStartOffset(lineNumber);
@@ -207,7 +217,7 @@ public class BaseIndentEnterHandler extends EnterHandlerDelegateAdapter {
}
@Nullable
- private IElementType getNonWhitespaceElementType(final HighlighterIterator iterator, int currentLineStartOffset, final int prevLineStartOffset) {
+ protected IElementType getNonWhitespaceElementType(final HighlighterIterator iterator, int currentLineStartOffset, final int prevLineStartOffset) {
while (!iterator.atEnd() && iterator.getEnd() >= currentLineStartOffset && iterator.getStart() >= prevLineStartOffset) {
final IElementType tokenType = iterator.getTokenType();
if (!myWhitespaceTokens.contains(tokenType)) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java
index 026564d7d2a0..a965a850b2fa 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java
@@ -39,7 +39,6 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.ui.LightweightHint;
import com.intellij.util.containers.WeakList;
-import com.intellij.util.ui.UIUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -184,7 +183,7 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec
@Override
public void releaseFoldings(@NotNull Editor editor) {
- ApplicationManager.getApplication().assertIsDispatchThread();
+ ApplicationManagerEx.getApplicationEx().assertIsDispatchThread(editor.getComponent());
final Project project = editor.getProject();
if (project != null && (!project.equals(myProject) || !project.isOpen())) return;
@@ -217,32 +216,26 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec
PsiDocumentManager.getInstance(myProject).commitDocument(document);
- Runnable operation = new Runnable() {
+ Runnable runnable = updateFoldRegions(editor, true, true);
+ if (runnable != null) {
+ runnable.run();
+ }
+ if (myProject.isDisposed() || editor.isDisposed()) return;
+ foldingModel.runBatchFoldingOperation(new Runnable() {
@Override
public void run() {
- Runnable runnable = updateFoldRegions(editor, true, true);
- if (runnable != null) {
- runnable.run();
+ DocumentFoldingInfo documentFoldingInfo = getDocumentFoldingInfo(document);
+ Editor[] editors = EditorFactory.getInstance().getEditors(document, myProject);
+ for (Editor otherEditor : editors) {
+ if (otherEditor == editor) continue;
+ documentFoldingInfo.loadFromEditor(otherEditor);
+ break;
}
- if (myProject.isDisposed() || editor.isDisposed()) return;
- foldingModel.runBatchFoldingOperation(new Runnable() {
- @Override
- public void run() {
- DocumentFoldingInfo documentFoldingInfo = getDocumentFoldingInfo(document);
- Editor[] editors = EditorFactory.getInstance().getEditors(document, myProject);
- for (Editor otherEditor : editors) {
- if (otherEditor == editor) continue;
- documentFoldingInfo.loadFromEditor(otherEditor);
- break;
- }
- documentFoldingInfo.setToEditor(editor);
+ documentFoldingInfo.setToEditor(editor);
- documentFoldingInfo.clear();
- }
- });
+ documentFoldingInfo.clear();
}
- };
- UIUtil.invokeLaterIfNeeded(operation);
+ });
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java
index 0e420b04de2d..9294f108eb75 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java
@@ -21,6 +21,7 @@ import com.intellij.lang.folding.FoldingBuilder;
import com.intellij.lang.folding.FoldingDescriptor;
import com.intellij.lang.folding.LanguageFolding;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -38,7 +39,6 @@ import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
import java.util.*;
class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState {
@@ -64,7 +64,7 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState {
}
void loadFromEditor(@NotNull Editor editor) {
- assertDispatchThread();
+ assertDispatchThread(editor);
LOG.assertTrue(!editor.isDisposed());
clear();
@@ -95,12 +95,12 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState {
}
}
- private static void assertDispatchThread() {
- assert SwingUtilities.isEventDispatchThread() : Thread.currentThread();
+ private static void assertDispatchThread(@NotNull Editor editor) {
+ ApplicationManagerEx.getApplicationEx().assertIsDispatchThread(editor.getComponent());
}
void setToEditor(@NotNull final Editor editor) {
- assertDispatchThread();
+ assertDispatchThread(editor);
final PsiManager psiManager = PsiManager.getInstance(myProject);
if (psiManager.isDisposed()) return;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlighter.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlighter.java
index 597610416c9f..52b955ef73c7 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlighter.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlighter.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,7 +42,7 @@ public class BraceHighlighter implements StartupActivity {
public void runActivity(@NotNull final Project project) {
final EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster();
- CaretListener myCaretListener = new CaretListener() {
+ CaretListener myCaretListener = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
myAlarm.cancelAllRequests();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
index 77944cfd7e30..237d55118a5f 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
@@ -251,19 +251,24 @@ public class ParameterInfoComponent extends JPanel {
int lineOffset = 0;
+ boolean hasHighlighting = highlightStartOffset >= 0 && highlightEndOffset > highlightStartOffset;
+ TextRange highlightingRange = hasHighlighting ? new TextRange(highlightStartOffset, highlightEndOffset) : null;
+
for (int i = 0; i < lines.length; i++) {
- String line = escapeString(lines[i]);
+ String line = lines[i];
myOneLineComponents[i] = new OneLineComponent();
- TextRange range = null;
- if (highlightStartOffset >= 0 && highlightEndOffset > lineOffset && highlightStartOffset < lineOffset + line.length()) {
- int startOffset = Math.max(highlightStartOffset - lineOffset, 0);
- int endOffset = Math.min(highlightEndOffset - lineOffset, line.length());
- range = TextRange.create(startOffset, endOffset);
- }
+ TextRange lRange = new TextRange(lineOffset, lineOffset + line.length());
+ TextRange hr = highlightingRange == null ? null : lRange.intersection(highlightingRange);
+ hr = hr == null ? null : hr.shiftRight(-lineOffset);
+
+ String before = escapeString(hr == null ? line : line.substring(0, hr.getStartOffset()));
+ String in = hr == null ? "" : escapeString(hr.substring(line));
+ String after = hr == null ? "" : escapeString(line.substring(hr.getEndOffset(), line.length()));
- buf.append(myOneLineComponents[i].setup(line, isDisabled, strikeout, background, range));
+ TextRange escapedHighlightingRange = in.isEmpty() ? null : TextRange.create(before.length(), before.length() + in.length());
+ buf.append(myOneLineComponents[i].setup(before + in + after, isDisabled, strikeout, background, escapedHighlightingRange));
if (isDisabledBeforeHighlight) {
if (highlightStartOffset < 0 || highlightEndOffset > lineOffset) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java
index 533562858621..73ad86b2fa72 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.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,10 +25,7 @@ import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.ScrollType;
-import com.intellij.openapi.editor.event.CaretEvent;
-import com.intellij.openapi.editor.event.CaretListener;
-import com.intellij.openapi.editor.event.DocumentAdapter;
-import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
@@ -177,7 +174,7 @@ public class ParameterInfoController implements Disposable {
List<ParameterInfoController> allControllers = getAllControllers(myEditor);
allControllers.add(this);
- myEditorCaretListener = new CaretListener(){
+ myEditorCaretListener = new CaretAdapter(){
@Override
public void caretPositionChanged(CaretEvent e) {
myAlarm.cancelAllRequests();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java
index 114d493898cc..b50395009c34 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java
@@ -117,10 +117,15 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable {
final String newFileName =
StringUtil.notNullize(language.getDisplayName(), "Injected") + " Fragment " + "(" +
origFile.getName() + ":" + shreds.get(0).getHost().getTextRange().getStartOffset() + ")" + "." + fileType.getDefaultExtension();
+
+ // preserve \r\n as it is done in MultiHostRegistrarImpl
myNewFile = factory.createFileFromText(newFileName, language, text, true, true);
- myNewVirtualFile = (LightVirtualFile)myNewFile.getVirtualFile();
+ myNewVirtualFile = ObjectUtils.assertNotNull((LightVirtualFile)myNewFile.getVirtualFile());
+ myNewVirtualFile.setOriginalFile(origFile.getVirtualFile());
+
+ assert myNewFile != null : "PSI file is null";
+ assert myNewFile.getTextLength() == myNewVirtualFile.getLength() : "PSI / Virtual file text mismatch";
myNewVirtualFile.setOriginalFile(origFile.getVirtualFile());
- assert myNewVirtualFile != null;
// suppress possible errors as in injected mode
myNewFile.putUserData(InjectedLanguageUtil.FRANKENSTEIN_INJECTION,
injectedFile.getUserData(InjectedLanguageUtil.FRANKENSTEIN_INJECTION));
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 26115d4b307e..cecdce57dad0 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
@@ -868,7 +868,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
}
}, this);
- final CaretListener caretListener = new CaretListener() {
+ final CaretListener caretListener = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
if (!myChangeGuard && !myFinishing) {
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 be95eed73160..9d8c67938907 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
@@ -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.
@@ -80,7 +80,7 @@ public class LookupTypedHandler extends TypedHandlerDelegate {
if (!lookup.performGuardedChange(new Runnable() {
@Override
public void run() {
- EditorModificationUtil.typeInStringAtCaretHonorBlockSelection(editor, String.valueOf(charTyped), true);
+ EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, String.valueOf(charTyped), true);
}
})) {
return Result.STOP;
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 3e0e26424bb5..1ee91b8212b8 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.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.
@@ -250,7 +250,7 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
EditorEventMulticaster eventMulticaster = editorFactory.getEventMulticaster();
eventMulticaster.addEditorMouseListener(myEditorMouseAdapter, project);
eventMulticaster.addEditorMouseMotionListener(myEditorMouseMotionListener, project);
- eventMulticaster.addCaretListener(new CaretListener() {
+ eventMulticaster.addCaretListener(new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
if (myHint != null) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/IncrementalSearchHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/IncrementalSearchHandler.java
index 36e5d2988029..fc0aed021ceb 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/IncrementalSearchHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/IncrementalSearchHandler.java
@@ -170,7 +170,7 @@ public class IncrementalSearchHandler {
};
document.addDocumentListener(documentListener[0]);
- caretListener[0] = new CaretListener() {
+ caretListener[0] = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
PerHintSearchData data = hint.getUserData(SEARCH_DATA_IN_HINT_KEY);
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 72d6d056080d..d3f658cdcf24 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
@@ -34,10 +34,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
-import com.intellij.openapi.editor.event.CaretEvent;
-import com.intellij.openapi.editor.event.DocumentAdapter;
-import com.intellij.openapi.editor.event.DocumentEvent;
-import com.intellij.openapi.editor.event.MultipleCaretListener;
+import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.markup.HighlighterLayer;
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
@@ -86,7 +83,7 @@ public class TemplateState implements Disposable {
private boolean myDocumentChanged = false;
@Nullable private CommandAdapter myCommandListener;
- @Nullable private MultipleCaretListener myCaretListener;
+ @Nullable private CaretListener myCaretListener;
private final List<TemplateEditingListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private DocumentAdapter myEditorDocumentListener;
@@ -146,7 +143,7 @@ public class TemplateState implements Disposable {
}
};
- myCaretListener = new MultipleCaretListener() {
+ myCaretListener = new CaretAdapter() {
@Override
public void caretAdded(CaretEvent e) {
if (isMultiCaretMode()) {
@@ -160,9 +157,6 @@ public class TemplateState implements Disposable {
finishTemplateEditing(false);
}
}
-
- @Override
- public void caretPositionChanged(CaretEvent e) {}
};
if (myEditor != null) {
@@ -173,7 +167,7 @@ public class TemplateState implements Disposable {
}
private boolean isMultiCaretMode() {
- return myEditor != null && myEditor.getCaretModel().supportsMultipleCarets() && myEditor.getCaretModel().getAllCarets().size() > 1;
+ return myEditor != null && myEditor.getCaretModel().getCaretCount() > 1;
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/execution/actions/StopProcessAction.java b/platform/lang-impl/src/com/intellij/execution/actions/StopProcessAction.java
index e38cac95243c..652ea0871215 100644
--- a/platform/lang-impl/src/com/intellij/execution/actions/StopProcessAction.java
+++ b/platform/lang-impl/src/com/intellij/execution/actions/StopProcessAction.java
@@ -32,13 +32,17 @@ import javax.swing.*;
*/
public class StopProcessAction extends DumbAwareAction implements AnAction.TransparentUpdate {
- private final ProcessHandler myProcessHandler;
+ private ProcessHandler myProcessHandler;
- public StopProcessAction(@NotNull String text, @Nullable String description, @NotNull ProcessHandler processHandler) {
+ public StopProcessAction(@NotNull String text, @Nullable String description, @Nullable ProcessHandler processHandler) {
super(text, description, AllIcons.Actions.Suspend);
myProcessHandler = processHandler;
}
+ public void setProcessHandler(@Nullable ProcessHandler processHandler) {
+ myProcessHandler = processHandler;
+ }
+
@Override
public void update(final AnActionEvent e) {
update(e.getPresentation(), getTemplatePresentation(), myProcessHandler);
@@ -72,7 +76,7 @@ public class StopProcessAction extends DumbAwareAction implements AnAction.Trans
stopProcess(myProcessHandler);
}
- public static void stopProcess(@NotNull ProcessHandler processHandler) {
+ public static void stopProcess(@Nullable ProcessHandler processHandler) {
if (processHandler instanceof KillableProcess && processHandler.isProcessTerminating()) {
// process termination was requested, but it's still alive
// in this case 'force quit' will be performed
@@ -80,11 +84,13 @@ public class StopProcessAction extends DumbAwareAction implements AnAction.Trans
return;
}
- if (processHandler.detachIsDefault()) {
- processHandler.detachProcess();
- }
- else {
- processHandler.destroyProcess();
+ if (processHandler != null) {
+ if (processHandler.detachIsDefault()) {
+ processHandler.detachProcess();
+ }
+ else {
+ processHandler.destroyProcess();
+ }
}
}
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 9f8900eacbdd..bcb78d83ae64 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java
@@ -24,10 +24,12 @@ import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.command.impl.UndoManagerImpl;
import com.intellij.openapi.command.undo.DocumentReferenceManager;
import com.intellij.openapi.command.undo.UndoManager;
+import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
+import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -110,23 +112,39 @@ public class ConsoleExecuteAction extends DumbAwareAction {
myExecuteActionHandler.runExecuteAction(myConsole, myConsoleView);
}
- protected boolean isEnabled() {
+ public boolean isEnabled() {
return myEnabledCondition.value(myConsole);
}
+ public void execute(@Nullable TextRange range, @NotNull String text, @Nullable EditorEx editor) {
+ if (range == null) {
+ myConsole.doAddPromptToHistory();
+ DocumentEx document = myConsole.getHistoryViewer().getDocument();
+ document.insertString(document.getTextLength(), text);
+ if (!text.endsWith("\n")) {
+ document.insertString(document.getTextLength(), "\n");
+ }
+ }
+ else {
+ assert editor != null;
+ myConsole.addTextRangeToHistory(range, editor, myExecuteActionHandler.myPreserveMarkup);
+ }
+ myExecuteActionHandler.addToCommandHistoryAndExecute(myConsole, myConsoleView, text);
+ }
+
static abstract class ConsoleExecuteActionHandler {
- private final ConsoleHistoryModel myConsoleHistoryModel;
+ private final ConsoleHistoryModel myCommandHistoryModel;
private boolean myAddToHistory = true;
final boolean myPreserveMarkup;
public ConsoleExecuteActionHandler(boolean preserveMarkup) {
- myConsoleHistoryModel = new ConsoleHistoryModel();
+ myCommandHistoryModel = new ConsoleHistoryModel();
myPreserveMarkup = preserveMarkup;
}
public ConsoleHistoryModel getConsoleHistoryModel() {
- return myConsoleHistoryModel;
+ return myCommandHistoryModel;
}
public boolean isEmptyCommandExecutionAllowed() {
@@ -139,10 +157,12 @@ public class ConsoleExecuteAction extends DumbAwareAction {
final void runExecuteAction(@NotNull LanguageConsoleImpl console, @Nullable LanguageConsoleView consoleView) {
String text = console.prepareExecuteAction(myAddToHistory, myPreserveMarkup, true);
-
((UndoManagerImpl)UndoManager.getInstance(console.getProject())).invalidateActionsFor(DocumentReferenceManager.getInstance().create(console.getCurrentEditor().getDocument()));
+ addToCommandHistoryAndExecute(console, consoleView, text);
+ }
- myConsoleHistoryModel.addToHistory(text);
+ private void addToCommandHistoryAndExecute(@NotNull LanguageConsoleImpl console, @Nullable LanguageConsoleView consoleView, @NotNull String text) {
+ myCommandHistoryModel.addToHistory(text);
doExecute(text, console, consoleView);
}
diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleGutterComponent.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleGutterComponent.java
index f7a1d6cc80fd..e9881c3b6007 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleGutterComponent.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleGutterComponent.java
@@ -3,8 +3,6 @@ package com.intellij.execution.console;
import com.intellij.codeInsight.hint.TooltipController;
import com.intellij.codeInsight.hint.TooltipGroup;
import com.intellij.ide.ui.UISettings;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.VisualPosition;
import com.intellij.openapi.editor.colors.EditorFontType;
@@ -29,27 +27,38 @@ class ConsoleGutterComponent extends JComponent implements MouseMotionListener {
private final EditorImpl editor;
- private int maxAnnotationWidth = 0;
+ private int maxContentWidth;
private int myLastPreferredHeight = -1;
- private final int lineEndInset;
+ private final int gap;
private final GutterContentProvider gutterContentProvider;
private int lastGutterToolTipLine = -1;
- public ConsoleGutterComponent(@NotNull Editor editor, @NotNull GutterContentProvider provider) {
- this.editor = (EditorImpl)editor;
- gutterContentProvider = provider;
- addListeners();
+ private final boolean atLineStart;
- addMouseMotionListener(this);
+ public ConsoleGutterComponent(@NotNull Editor editor, @NotNull GutterContentProvider gutterContentProvider, boolean atLineStart) {
+ this.editor = (EditorImpl)editor;
+ this.gutterContentProvider = gutterContentProvider;
+ this.atLineStart = atLineStart;
- setOpaque(true);
+ if (atLineStart) {
+ setOpaque(gutterContentProvider.getLineStartGutterOverlap(editor) == 0);
+ }
+ else {
+ addListeners();
+ setOpaque(false);
+ }
- lineEndInset = EditorUtil.getSpaceWidth(Font.PLAIN, editor);
+ int spaceWidth = EditorUtil.getSpaceWidth(Font.PLAIN, editor);
+ // at line start: icon/one-char symbol + space
+ gap = atLineStart ? spaceWidth * GutterContentProvider.MAX_LINE_END_GUTTER_WIDTH_IN_CHAR : spaceWidth;
+ maxContentWidth = atLineStart ? gap : 0;
}
private void addListeners() {
+ addMouseMotionListener(this);
+
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
@@ -61,9 +70,9 @@ class ConsoleGutterComponent extends JComponent implements MouseMotionListener {
}
public void updateSize(int start, int end) {
- int oldAnnotationsWidth = maxAnnotationWidth;
+ int oldAnnotationsWidth = maxContentWidth;
computeMaxAnnotationWidth(start, end);
- if (oldAnnotationsWidth != maxAnnotationWidth || myLastPreferredHeight != editor.getPreferredHeight()) {
+ if (oldAnnotationsWidth != maxContentWidth || myLastPreferredHeight != editor.getPreferredHeight()) {
processComponentEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED));
}
repaint();
@@ -72,8 +81,13 @@ class ConsoleGutterComponent extends JComponent implements MouseMotionListener {
private void computeMaxAnnotationWidth(int start, int end) {
gutterContentProvider.beforeUiComponentUpdate(editor);
+ if (atLineStart) {
+ return;
+ }
+
if (!gutterContentProvider.hasText()) {
- maxAnnotationWidth = 0;
+ editor.getSettings().setAdditionalColumnsCount(1);
+ maxContentWidth = 0;
return;
}
@@ -87,46 +101,51 @@ class ConsoleGutterComponent extends JComponent implements MouseMotionListener {
}
}
+ // line start gutter always has gap
if (gutterSize != 0) {
- gutterSize += lineEndInset;
+ gutterSize += gap;
}
- maxAnnotationWidth = Math.max(gutterSize, maxAnnotationWidth);
+ maxContentWidth = Math.max(gutterSize, maxContentWidth);
- editor.getSettings().setAdditionalColumnsCount(1 + (maxAnnotationWidth / EditorUtil.getSpaceWidth(Font.PLAIN, editor)));
+ editor.getSettings().setAdditionalColumnsCount(1 + (maxContentWidth / EditorUtil.getSpaceWidth(Font.PLAIN, editor)));
}
@Override
public Dimension getPreferredSize() {
myLastPreferredHeight = editor.getPreferredHeight();
- return new Dimension(maxAnnotationWidth, myLastPreferredHeight);
+ return new Dimension(maxContentWidth, myLastPreferredHeight);
}
@Override
public void paint(Graphics g) {
- ((ApplicationImpl)ApplicationManager.getApplication()).editorPaintStart();
- try {
- Rectangle clip = g.getClipBounds();
- if (clip.height < 0 || maxAnnotationWidth == 0) {
+ Rectangle clip = g.getClipBounds();
+ if (clip.height <= 0 || maxContentWidth == 0) {
+ return;
+ }
+
+ if (atLineStart) {
+ // don't paint in the overlapped region
+ if (clip.x >= maxContentWidth) {
return;
}
- UISettings.setupAntialiasing(g);
+ g.setColor(editor.getBackgroundColor());
+ g.fillRect(clip.x, clip.y, Math.min(clip.width, maxContentWidth - clip.x), clip.height);
+ }
- Graphics2D g2 = (Graphics2D)g;
- Object hint = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
- if (!UIUtil.isRetina()) {
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
- }
+ UISettings.setupAntialiasing(g);
- try {
- paintAnnotations(g, clip);
- }
- finally {
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, hint);
- }
+ Graphics2D g2 = (Graphics2D)g;
+ Object hint = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
+ if (!UIUtil.isRetina()) {
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ }
+
+ try {
+ paintAnnotations(g, clip);
}
finally {
- ((ApplicationImpl)ApplicationManager.getApplication()).editorPaintFinish();
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, hint);
}
}
@@ -138,17 +157,24 @@ class ConsoleGutterComponent extends JComponent implements MouseMotionListener {
return;
}
- gutterContentProvider.beforeUiComponentUpdate(editor);
-
- g.setColor(JBColor.BLUE);
+ if (!atLineStart) {
+ g.setColor(JBColor.BLUE);
+ }
g.setFont(editor.getColorsScheme().getFont(EditorFontType.PLAIN));
+
int y = ((startLine + 1) * lineHeight) - editor.getDescent();
FontMetrics fontMetrics = editor.getFontMetrics(Font.PLAIN);
- for (int i = startLine; i < endLine; i++) {
- String text = gutterContentProvider.getText(editor.visualToLogicalPosition(new VisualPosition(i, 0)).line, editor);
- if (text != null) {
- // right-aligned
- g.drawString(text, maxAnnotationWidth - lineEndInset - fontMetrics.stringWidth(text), y);
+ for (int line = startLine; line < endLine; line++) {
+ int logicalLine = editor.visualToLogicalPosition(new VisualPosition(line, 0)).line;
+ if (atLineStart) {
+ gutterContentProvider.drawIcon(logicalLine, g, y, editor);
+ }
+ else {
+ String text = gutterContentProvider.getText(logicalLine, editor);
+ if (text != null) {
+ // right-aligned
+ g.drawString(text, maxContentWidth - gap - fontMetrics.stringWidth(text), y);
+ }
}
y += lineHeight;
}
@@ -190,6 +216,8 @@ class ConsoleGutterComponent extends JComponent implements MouseMotionListener {
}
public void documentCleared() {
- maxAnnotationWidth = 0;
+ if (!atLineStart) {
+ maxContentWidth = 0;
+ }
}
} \ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleIconGutterComponent.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleIconGutterComponent.java
deleted file mode 100644
index ec57b2108a71..000000000000
--- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleIconGutterComponent.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package com.intellij.execution.console;
-
-import com.intellij.ide.ui.UISettings;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.impl.ApplicationImpl;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.VisualPosition;
-import com.intellij.openapi.editor.colors.EditorFontType;
-import com.intellij.openapi.editor.ex.util.EditorUtil;
-import com.intellij.openapi.editor.impl.EditorImpl;
-import com.intellij.util.ui.UIUtil;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ComponentEvent;
-
-class ConsoleIconGutterComponent extends JComponent {
- private final int iconAreaWidth;
-
- private int myLastPreferredHeight = -1;
- private final EditorImpl editor;
-
- private final GutterContentProvider gutterContentProvider;
-
- public ConsoleIconGutterComponent(@NotNull Editor editor, @NotNull GutterContentProvider provider) {
- this.editor = (EditorImpl)editor;
- gutterContentProvider = provider;
-
- // icon/one-char symbol + space
- iconAreaWidth = EditorUtil.getSpaceWidth(Font.PLAIN, editor) * 2;
- }
-
- public void updateSize() {
- if (myLastPreferredHeight != editor.getPreferredHeight()) {
- fireResized();
- }
- repaint();
- }
-
- private void fireResized() {
- processComponentEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED));
- }
-
- @Override
- public Dimension getPreferredSize() {
- myLastPreferredHeight = editor.getPreferredHeight();
- return new Dimension(iconAreaWidth, myLastPreferredHeight);
- }
-
- @Override
- public void paint(Graphics g) {
- ((ApplicationImpl)ApplicationManager.getApplication()).editorPaintStart();
- try {
- Rectangle clip = g.getClipBounds();
- if (clip.height < 0) {
- return;
- }
-
- g.setColor(editor.getBackgroundColor());
- g.fillRect(clip.x, clip.y, clip.width, clip.height);
-
- UISettings.setupAntialiasing(g);
-
- Graphics2D g2 = (Graphics2D)g;
- Object hint = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
- if (!UIUtil.isRetina()) {
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
- }
-
- try {
- paintAnnotations(g, clip);
- }
- finally {
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, hint);
- }
- }
- finally {
- ((ApplicationImpl)ApplicationManager.getApplication()).editorPaintFinish();
- }
- }
-
- private void paintAnnotations(Graphics g, Rectangle clip) {
- int lineHeight = editor.getLineHeight();
- int startLine = clip.y / lineHeight;
- int endLine = Math.min(((clip.y + clip.height) / lineHeight) + 1, editor.getVisibleLineCount());
- if (startLine >= endLine) {
- return;
- }
-
- g.setFont(editor.getColorsScheme().getFont(EditorFontType.PLAIN));
- int y = ((startLine + 1) * lineHeight) - editor.getDescent();
- for (int i = startLine; i < endLine; i++) {
- gutterContentProvider.drawIcon(editor.visualToLogicalPosition(new VisualPosition(i, 0)).line, g, y, editor);
- y += lineHeight;
- }
- }
-} \ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/execution/console/GutterContentProvider.java b/platform/lang-impl/src/com/intellij/execution/console/GutterContentProvider.java
index c283b1a53fdc..c2eed1a09cd3 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/GutterContentProvider.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/GutterContentProvider.java
@@ -7,6 +7,8 @@ import org.jetbrains.annotations.Nullable;
import java.awt.*;
public abstract class GutterContentProvider {
+ protected static final int MAX_LINE_END_GUTTER_WIDTH_IN_CHAR = 2;
+
public void beforeUiComponentUpdate(@NotNull Editor editor) {
}
@@ -31,4 +33,8 @@ public abstract class GutterContentProvider {
public boolean isShowSeparatorLine(int line, @NotNull Editor editor) {
return true;
}
+
+ public int getLineStartGutterOverlap(@NotNull Editor editor) {
+ return 0;
+ }
} \ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleBuilder.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleBuilder.java
index 0d013fbfec1c..22b82c803c74 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleBuilder.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleBuilder.java
@@ -147,7 +147,7 @@ public final class LanguageConsoleBuilder {
}
public LanguageConsoleView build(@NotNull Project project, @NotNull Language language) {
- GutteredLanguageConsole console = new GutteredLanguageConsole(project, language, gutterContentProvider, psiFileFactory);
+ GutteredLanguageConsole console = new GutteredLanguageConsole(language.getDisplayName() + " Console", project, language, gutterContentProvider, psiFileFactory);
LanguageConsoleViewImpl consoleView = new LanguageConsoleViewImpl(console, true);
if (executeActionHandler != null) {
assert historyType != null;
@@ -184,11 +184,12 @@ public final class LanguageConsoleBuilder {
@Nullable
private final PairFunction<VirtualFile, Project, PsiFile> psiFileFactory;
- public GutteredLanguageConsole(@NotNull Project project,
+ public GutteredLanguageConsole(@NotNull String title,
+ @NotNull Project project,
@NotNull Language language,
@Nullable GutterContentProvider gutterContentProvider,
@Nullable PairFunction<VirtualFile, Project, PsiFile> psiFileFactory) {
- super(project, language.getDisplayName() + " Console", language, false);
+ super(project, title, new LightVirtualFile(title, language, ""), false, psiFileFactory);
setShowSeparatorLine(false);
@@ -201,6 +202,11 @@ public final class LanguageConsoleBuilder {
return gutterContentProvider == null;
}
+ @Override
+ int getMinHistoryLineCount() {
+ return 1;
+ }
+
@NotNull
@Override
protected PsiFile createFile(@NotNull LightVirtualFile virtualFile, @NotNull Document document, @NotNull Project project) {
@@ -224,8 +230,8 @@ public final class LanguageConsoleBuilder {
return;
}
- final ConsoleIconGutterComponent lineStartGutter = new ConsoleIconGutterComponent(editor, gutterContentProvider);
- final ConsoleGutterComponent lineEndGutter = new ConsoleGutterComponent(editor, gutterContentProvider);
+ final ConsoleGutterComponent lineStartGutter = new ConsoleGutterComponent(editor, gutterContentProvider, true);
+ final ConsoleGutterComponent lineEndGutter = new ConsoleGutterComponent(editor, gutterContentProvider, false);
JLayeredPane layeredPane = new JBLayeredPane() {
@Override
public Dimension getPreferredSize() {
@@ -245,7 +251,7 @@ public final class LanguageConsoleBuilder {
int w = getWidth();
int h = getHeight();
int lineStartGutterWidth = lineStartGutter.getPreferredSize().width;
- lineStartGutter.setBounds(0, 0, lineStartGutterWidth, h);
+ lineStartGutter.setBounds(0, 0, lineStartGutterWidth + gutterContentProvider.getLineStartGutterOverlap(editor.getEditor()), h);
editor.setBounds(lineStartGutterWidth, 0, w - lineStartGutterWidth, h);
@@ -265,7 +271,7 @@ public final class LanguageConsoleBuilder {
}
};
- layeredPane.add(lineStartGutter, JLayeredPane.DEFAULT_LAYER);
+ layeredPane.add(lineStartGutter, JLayeredPane.PALETTE_LAYER);
JScrollPane scrollPane = editor.getScrollPane();
layeredPane.add(scrollPane.getViewport().getView(), JLayeredPane.DEFAULT_LAYER);
@@ -290,13 +296,13 @@ public final class LanguageConsoleBuilder {
}
private final class GutterUpdateScheduler extends DocumentAdapter implements DocumentBulkUpdateListener {
- private final ConsoleIconGutterComponent lineStartGutter;
+ private final ConsoleGutterComponent lineStartGutter;
private final ConsoleGutterComponent lineEndGutter;
private Task gutterSizeUpdater;
private RangeHighlighterEx lineSeparatorPainter;
- public GutterUpdateScheduler(@NotNull ConsoleIconGutterComponent lineStartGutter, @NotNull ConsoleGutterComponent lineEndGutter) {
+ public GutterUpdateScheduler(@NotNull ConsoleGutterComponent lineStartGutter, @NotNull ConsoleGutterComponent lineEndGutter) {
this.lineStartGutter = lineStartGutter;
this.lineEndGutter = lineEndGutter;
@@ -393,7 +399,7 @@ public final class LanguageConsoleBuilder {
@Override
public void run() {
if (!getHistoryViewer().isDisposed()) {
- lineStartGutter.updateSize();
+ lineStartGutter.updateSize(start, end);
lineEndGutter.updateSize(start, end);
}
gutterSizeUpdater = null;
diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java
index da38faf0f8f5..5b88d7c739a3 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.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.
@@ -58,10 +58,7 @@ import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.ui.JBColor;
import com.intellij.ui.SideBorder;
-import com.intellij.util.DocumentUtil;
-import com.intellij.util.FileContentUtil;
-import com.intellij.util.ObjectUtils;
-import com.intellij.util.SingleAlarm;
+import com.intellij.util.*;
import com.intellij.util.ui.AbstractLayoutManager;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -124,6 +121,14 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
}
public LanguageConsoleImpl(@NotNull Project project, @NotNull String title, @NotNull LightVirtualFile lightFile, boolean initComponents) {
+ this(project, title, lightFile, initComponents, null);
+ }
+
+ LanguageConsoleImpl(@NotNull Project project,
+ @NotNull String title,
+ @NotNull LightVirtualFile lightFile,
+ boolean initComponents,
+ @Nullable PairFunction<VirtualFile, Project, PsiFile> psiFileFactory) {
myProject = project;
myTitle = title;
myVirtualFile = lightFile;
@@ -131,7 +136,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
myHistoryFile = new LightVirtualFile(getTitle() + ".history.txt", FileTypes.PLAIN_TEXT, "");
myEditorDocument = FileDocumentManager.getInstance().getDocument(lightFile);
assert myEditorDocument != null;
- myFile = createFile(myVirtualFile, myEditorDocument, myProject);
+ myFile = psiFileFactory == null ? createFile(myVirtualFile, myEditorDocument, myProject) : psiFileFactory.fun(myVirtualFile, myProject);
myConsoleEditor = (EditorEx)editorFactory.createEditor(myEditorDocument, myProject);
myConsoleEditor.addFocusListener(myFocusListener);
myCurrentEditor = myConsoleEditor;
@@ -173,7 +178,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
myHistoryViewer.getComponent().addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
- if (myForceScrollToEnd.getAndSet(false)) {
+ if (myForceScrollToEnd.compareAndSet(true, false)) {
scrollHistoryToEnd();
}
}
@@ -333,6 +338,8 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
}
private void setPromptInner(@Nullable final String prompt) {
+ myUpdateQueue.checkDisposed();
+
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
@@ -472,20 +479,17 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
public boolean shouldScrollHistoryToEnd() {
final Rectangle visibleArea = myHistoryViewer.getScrollingModel().getVisibleArea();
final Dimension contentSize = myHistoryViewer.getContentSize();
- return contentSize.getHeight() - visibleArea.getMaxY() < 2 * myHistoryViewer.getLineHeight();
+ return contentSize.getHeight() - visibleArea.getMaxY() < (getMinHistoryLineCount() * myHistoryViewer.getLineHeight());
}
private void scrollHistoryToEnd() {
- final int lineCount = myHistoryViewer.getDocument().getLineCount();
- if (lineCount == 0) {
- return;
+ if (myHistoryViewer.getDocument().getTextLength() != 0) {
+ EditorUtil.scrollToTheEnd(myHistoryViewer);
}
- myHistoryViewer.getCaretModel().moveToOffset(myHistoryViewer.getDocument().getLineStartOffset(lineCount - 1), false);
- myHistoryViewer.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
}
@NotNull
- protected String addTextRangeToHistory(@NotNull TextRange textRange, @NotNull EditorEx consoleEditor, boolean preserveMarkup) {
+ protected String addTextRangeToHistory(@NotNull TextRange textRange, @NotNull EditorEx inputEditor, boolean preserveMarkup) {
doAddPromptToHistory();
final Document history = myHistoryViewer.getDocument();
@@ -493,16 +497,16 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
final int localStartOffset = textRange.getStartOffset();
String text;
EditorHighlighter highlighter;
- if (consoleEditor instanceof EditorWindow) {
- PsiFile file = ((EditorWindow)consoleEditor).getInjectedFile();
+ if (inputEditor instanceof EditorWindow) {
+ PsiFile file = ((EditorWindow)inputEditor).getInjectedFile();
highlighter = HighlighterFactory.createHighlighter(file.getVirtualFile(), EditorColorsManager.getInstance().getGlobalScheme(), getProject());
String fullText = InjectedLanguageUtil.getUnescapedText(file, null, null);
highlighter.setText(fullText);
text = textRange.substring(fullText);
}
else {
- text = consoleEditor.getDocument().getText(textRange);
- highlighter = consoleEditor.getHighlighter();
+ text = inputEditor.getDocument().getText(textRange);
+ highlighter = inputEditor.getHighlighter();
}
//offset can be changed after text trimming after insert due to buffer constraints
int offset = appendToHistoryDocument(history, text);
@@ -524,9 +528,9 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
iterator.advance();
}
if (preserveMarkup) {
- duplicateHighlighters(markupModel, DocumentMarkupModel.forDocument(consoleEditor.getDocument(), myProject, true), offset, textRange);
+ duplicateHighlighters(markupModel, DocumentMarkupModel.forDocument(inputEditor.getDocument(), myProject, true), offset, textRange);
// don't copy editor markup model, i.e. brace matcher, spell checker, etc.
- // duplicateHighlighters(markupModel, consoleEditor.getMarkupModel(), offset, textRange);
+ // duplicateHighlighters(markupModel, inputEditor.getMarkupModel(), offset, textRange);
}
if (!text.endsWith("\n")) {
appendToHistoryDocument(history, "\n");
@@ -623,7 +627,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
myCurrentEditor = editor;
}
EmptyAction.registerActionShortcuts(editor.getComponent(), myConsoleEditor.getComponent());
- editor.getCaretModel().addCaretListener(new CaretListener() {
+ editor.getCaretModel().addCaretListener(new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
queueUiUpdate(false);
@@ -686,6 +690,10 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
return true;
}
+ int getMinHistoryLineCount() {
+ return 2;
+ }
+
private class MyLayout extends AbstractLayoutManager {
@Override
public Dimension preferredLayoutSize(final Container parent) {
@@ -700,8 +708,8 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
}
final EditorEx history = myHistoryViewer;
- final EditorEx editor = componentCount == 2 ? myConsoleEditor : null;
- if (editor == null) {
+ final EditorEx input = componentCount == 2 ? myConsoleEditor : null;
+ if (input == null) {
parent.getComponent(0).setBounds(parent.getBounds());
return;
}
@@ -711,44 +719,44 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
return;
}
final Dimension historySize = history.getContentSize();
- final Dimension editorSize = editor.getContentSize();
- final Dimension newEditorSize = new Dimension();
+ final Dimension inputSize = input.getContentSize();
+ int newInputHeight;
// deal with width
- final int width = Math.max(editorSize.width, historySize.width);
- newEditorSize.width = width + editor.getScrollPane().getHorizontalScrollBar().getHeight();
+ final int width = Math.max(inputSize.width, historySize.width);
if (isHistoryViewerForceAdditionalColumnsUsage()) {
history.getSoftWrapModel().forceAdditionalColumnsUsage();
- editor.getSettings().setAdditionalColumnsCount(2 + (width - editorSize.width) / EditorUtil.getSpaceWidth(Font.PLAIN, editor));
+ input.getSettings().setAdditionalColumnsCount(2 + (width - inputSize.width) / EditorUtil.getSpaceWidth(Font.PLAIN, input));
history.getSettings().setAdditionalColumnsCount(2 + (width - historySize.width) / EditorUtil.getSpaceWidth(Font.PLAIN, history));
}
- // deal with height
- if (historySize.width == 0) {
+ // deal with height, WEB-11122 we cannot trust editor width — it could be 0 in case of soft wrap even if editor has text
+ if (history.getDocument().getLineCount() == 0) {
historySize.height = 0;
}
- final int minHistorySize = historySize.height > 0 ? 2 * history.getLineHeight() + (myShowSeparatorLine ? SEPARATOR_THICKNESS : 0) : 0;
- final int minEditorSize = editor.isViewer() ? 0 : editor.getLineHeight();
- final int editorPreferred = editor.isViewer() ? 0 : Math.max(minEditorSize, editorSize.height);
- final int historyPreferred = Math.max(minHistorySize, historySize.height);
- if (panelSize.height < minEditorSize) {
- newEditorSize.height = panelSize.height;
+
+ int minHistoryHeight = historySize.height > 0 ? (getMinHistoryLineCount() * history.getLineHeight() + (myShowSeparatorLine ? SEPARATOR_THICKNESS : 0)) : 0;
+ int minInputHeight = input.isViewer() ? 0 : input.getLineHeight();
+ final int inputPreferredHeight = input.isViewer() ? 0 : Math.max(minInputHeight, inputSize.height);
+ final int historyPreferredHeight = Math.max(minHistoryHeight, historySize.height);
+ if (panelSize.height < minInputHeight) {
+ newInputHeight = panelSize.height;
}
- else if (panelSize.height < editorPreferred) {
- newEditorSize.height = panelSize.height - minHistorySize;
+ else if (panelSize.height < inputPreferredHeight) {
+ newInputHeight = panelSize.height - minHistoryHeight;
}
- else if (panelSize.height < editorPreferred + historyPreferred) {
- newEditorSize.height = editorPreferred;
+ else if (panelSize.height < (inputPreferredHeight + historyPreferredHeight) || inputPreferredHeight == 0) {
+ newInputHeight = inputPreferredHeight;
}
else {
- newEditorSize.height = editorPreferred == 0 ? 0 : panelSize.height - historyPreferred;
+ newInputHeight = panelSize.height - historyPreferredHeight;
}
- final Dimension newHistorySize = new Dimension(width, panelSize.height - newEditorSize.height);
+ int newHistoryHeight = panelSize.height - newInputHeight;
// apply
- editor.getComponent().setBounds(0, newHistorySize.height, panelSize.width, newEditorSize.height);
+ input.getComponent().setBounds(0, newHistoryHeight, panelSize.width, newInputHeight);
myForceScrollToEnd.compareAndSet(false, shouldScrollHistoryToEnd());
- history.getComponent().setBounds(0, 0, panelSize.width, newHistorySize.height);
+ history.getComponent().setBounds(0, 0, panelSize.width, newHistoryHeight);
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
index f729219a5389..1c19e6988591 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
@@ -386,17 +386,22 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
}
public void requestScrollingToEnd() {
- if (myEditor == null || myFlushAlarm.isDisposed()) return;
- final MyFlushRunnable scrollRunnable = new MyFlushRunnable() {
+ if (myEditor == null || myFlushAlarm.isDisposed()) {
+ return;
+ }
+
+ addFlushRequest(new MyFlushRunnable() {
@Override
public void doRun() {
flushDeferredText();
- if (myEditor == null || myFlushAlarm.isDisposed()) return;
+ if (myEditor == null || myFlushAlarm.isDisposed()) {
+ return;
+ }
+
myEditor.getCaretModel().moveToOffset(myEditor.getDocument().getTextLength());
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
}
- };
- addFlushRequest(scrollRunnable);
+ });
}
private void addFlushRequest(MyFlushRunnable scrollRunnable) {
@@ -480,13 +485,12 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
// 'Debugger' tab is active while 'Console' is not). It's also possible that newly added text contains long lines that
// are soft wrapped. We want to update viewport position then when the console becomes visible.
final Rectangle oldRectangle = e.getOldRectangle();
- final Rectangle newRectangle = e.getNewRectangle();
if (oldRectangle == null) {
return;
}
Editor myEditor = e.getEditor();
- if (oldRectangle.height <= 0 && newRectangle.height > 0 && myEditor.getSoftWrapModel().isSoftWrappingEnabled()
+ if (oldRectangle.height <= 0 && e.getNewRectangle().height > 0 && myEditor.getSoftWrapModel().isSoftWrappingEnabled()
&& myEditor.getCaretModel().getOffset() == myEditor.getDocument().getTextLength()) {
EditorUtil.scrollToTheEnd(myEditor);
}
@@ -834,19 +838,14 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
return ApplicationManager.getApplication().runReadAction(new Computable<EditorEx>() {
@Override
public EditorEx compute() {
- final EditorEx editor = createRealEditor();
-
+ EditorEx editor = createRealEditor();
editor.addEditorMouseListener(new EditorPopupHandler() {
@Override
public void invokePopup(final EditorMouseEvent event) {
popupInvoked(event.getMouseEvent());
}
});
- editor.getDocument().addDocumentListener(new DocumentListener() {
- @Override
- public void beforeDocumentChange(DocumentEvent event) {
- }
-
+ editor.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent event) {
onDocumentChanged(event);
diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java
index e54074d08461..5c931bb26a5b 100644
--- a/platform/lang-impl/src/com/intellij/find/FindUtil.java
+++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java
@@ -34,6 +34,7 @@ import com.intellij.openapi.editor.actionSystem.EditorActionManager;
import com.intellij.openapi.editor.actions.IncrementalFindAction;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.event.CaretAdapter;
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.editor.ex.DocumentEx;
@@ -752,7 +753,7 @@ public class FindUtil {
return result;
}
- private static class MyListener implements CaretListener {
+ private static class MyListener extends CaretAdapter {
private final Editor myEditor;
private final RangeHighlighter mySegmentHighlighter;
@@ -818,7 +819,7 @@ public class FindUtil {
position = HintManager.ABOVE;
}
}
- CaretListener listener = new CaretListener() {
+ CaretListener listener = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
editor.putUserData(KEY, null);
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.java
index 1ceb62447573..755e2323c57c 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.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.find.editorHeaderActions;
import com.intellij.find.EditorSearchComponent;
@@ -5,7 +20,7 @@ import com.intellij.find.FindModel;
import com.intellij.openapi.actionSystem.AnActionEvent;
public class TogglePreserveCaseAction extends EditorHeaderToggleAction implements SecondaryHeaderAction {
- private static final String TEXT = "Preser&ve Case";
+ private static final String TEXT = "&Preserve Case";
public TogglePreserveCaseAction(EditorSearchComponent editorSearchComponent) {
super(editorSearchComponent, TEXT);
diff --git a/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java b/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java
index 4c11fe213535..7bc0e0c595f8 100644
--- a/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java
+++ b/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java
@@ -127,7 +127,7 @@ public class FindInProjectManager {
return processor.process(usage);
}
};
- FindInProjectUtil.findUsages(findModelCopy, psiDirectory, myProject, true, consumer, processPresentation);
+ FindInProjectUtil.findUsages(findModelCopy, psiDirectory, myProject, consumer, processPresentation);
}
finally {
myIsFindInProgress = false;
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
new file mode 100644
index 000000000000..3650e188a65e
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
@@ -0,0 +1,394 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.impl;
+
+import com.intellij.find.FindBundle;
+import com.intellij.find.FindModel;
+import com.intellij.find.ngrams.TrigramIndex;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ApplicationNamesInfo;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.progress.EmptyProgressIndicator;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectCoreUtil;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.util.text.TrigramBuilder;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileFilter;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.cache.CacheManager;
+import com.intellij.psi.impl.cache.impl.id.IdIndex;
+import com.intellij.psi.impl.search.PsiSearchHelperImpl;
+import com.intellij.psi.search.*;
+import com.intellij.usageView.UsageInfo;
+import com.intellij.usages.FindUsagesProcessPresentation;
+import com.intellij.usages.UsageLimitUtil;
+import com.intellij.usages.impl.UsageViewManagerImpl;
+import com.intellij.util.CommonProcessors;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.indexing.FileBasedIndex;
+import com.intellij.util.indexing.FileBasedIndexImpl;
+import gnu.trove.TIntHashSet;
+import gnu.trove.TIntIterator;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * @author peter
+ */
+class FindInProjectTask {
+ private static final int FILES_SIZE_LIMIT = 70 * 1024 * 1024; // megabytes.
+ private static final int SINGLE_FILE_SIZE_LIMIT = 5 * 1024 * 1024; // megabytes.
+ private final FindModel myFindModel;
+ private final Project myProject;
+ private final PsiManager myPsiManager;
+ @Nullable private final PsiDirectory myPsiDirectory;
+ private final FileIndex myFileIndex;
+ private final Condition<VirtualFile> myFileMask;
+ private final ProgressIndicator myProgress;
+ @Nullable private final Module myModule;
+ private final Set<PsiFile> myLargeFiles = ContainerUtil.newTroveSet();
+ private boolean myWarningShown;
+
+ FindInProjectTask(@NotNull final FindModel findModel,
+ @NotNull final Project project,
+ @Nullable final PsiDirectory psiDirectory) {
+ myFindModel = findModel;
+ myProject = project;
+ myPsiDirectory = psiDirectory;
+ myPsiManager = PsiManager.getInstance(project);
+
+ final String moduleName = findModel.getModuleName();
+ myModule = moduleName == null ? null : ApplicationManager.getApplication().runReadAction(new Computable<Module>() {
+ @Override
+ public Module compute() {
+ return ModuleManager.getInstance(project).findModuleByName(moduleName);
+ }
+ });
+ myFileIndex = myModule == null ?
+ ProjectRootManager.getInstance(project).getFileIndex() :
+ ModuleRootManager.getInstance(myModule).getFileIndex();
+
+ final String filter = findModel.getFileFilter();
+ final Pattern pattern = FindInProjectUtil.createFileMaskRegExp(filter);
+
+ //noinspection unchecked
+ myFileMask = pattern == null ? Condition.TRUE : new Condition<VirtualFile>() {
+ @Override
+ public boolean value(VirtualFile file) {
+ return file != null && pattern.matcher(file.getName()).matches();
+ }
+ };
+
+ final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
+ myProgress = progress != null ? progress : new EmptyProgressIndicator();
+ }
+
+ public void findUsages(@NotNull final Processor<UsageInfo> consumer, @NotNull FindUsagesProcessPresentation processPresentation) {
+ try {
+ myProgress.setIndeterminate(true);
+ myProgress.setText("Scanning indexed files...");
+ final Set<PsiFile> filesForFastWordSearch = getFilesForFastWordSearch();
+ myProgress.setIndeterminate(false);
+
+ searchInFiles(consumer, processPresentation, filesForFastWordSearch);
+
+ myProgress.setIndeterminate(true);
+ myProgress.setText("Scanning non-indexed files...");
+ final Collection<PsiFile> otherFiles = collectFilesInScope(filesForFastWordSearch);
+ myProgress.setIndeterminate(false);
+
+ searchInFiles(consumer, processPresentation, otherFiles);
+ }
+ catch (ProcessCanceledException e) {
+ // fine
+ }
+
+ if (!myLargeFiles.isEmpty()) {
+ processPresentation.setLargeFilesWereNotScanned(myLargeFiles);
+ }
+
+ if (!myProgress.isCanceled()) {
+ myProgress.setText(FindBundle.message("find.progress.search.completed"));
+ }
+ }
+
+ private void searchInFiles(Processor<UsageInfo> consumer, FindUsagesProcessPresentation processPresentation, Collection<PsiFile> psiFiles) {
+ int i = 0;
+ long totalFilesSize = 0;
+ int count = 0;
+
+ for (final PsiFile psiFile : psiFiles) {
+ final VirtualFile virtualFile = psiFile.getVirtualFile();
+ final int index = i++;
+ if (virtualFile == null) continue;
+
+ long fileLength = UsageViewManagerImpl.getFileLength(virtualFile);
+ if (fileLength == -1) continue; // Binary or invalid
+
+ if (ProjectCoreUtil.isProjectOrWorkspaceFile(virtualFile) && !Registry.is("find.search.in.project.files")) continue;
+
+ if (fileLength > SINGLE_FILE_SIZE_LIMIT) {
+ myLargeFiles.add(psiFile);
+ continue;
+ }
+
+ myProgress.checkCanceled();
+ myProgress.setFraction((double)index / psiFiles.size());
+ String text = FindBundle.message("find.searching.for.string.in.file.progress",
+ myFindModel.getStringToFind(), virtualFile.getPresentableUrl());
+ myProgress.setText(text);
+ myProgress.setText2(FindBundle.message("find.searching.for.string.in.file.occurrences.progress", count));
+
+ int countInFile = FindInProjectUtil.processUsagesInFile(psiFile, myFindModel, consumer);
+
+ count += countInFile;
+ if (countInFile > 0) {
+ totalFilesSize += fileLength;
+ if (totalFilesSize > FILES_SIZE_LIMIT && !myWarningShown) {
+ myWarningShown = true;
+ String message = FindBundle.message("find.excessive.total.size.prompt",
+ UsageViewManagerImpl.presentableSize(totalFilesSize),
+ ApplicationNamesInfo.getInstance().getProductName());
+ UsageLimitUtil.showAndCancelIfAborted(myProject, message, processPresentation.getUsageViewPresentation());
+ }
+ }
+ }
+ }
+
+ @NotNull
+ private Collection<PsiFile> collectFilesInScope(@NotNull final Set<PsiFile> alreadySearched) {
+ SearchScope customScope = myFindModel.getCustomScope();
+ final GlobalSearchScope globalCustomScope = toGlobal(customScope);
+
+ final boolean skipIndexed = canRelyOnIndices();
+
+ class EnumContentIterator implements ContentIterator {
+ final Set<PsiFile> myFiles = new LinkedHashSet<PsiFile>();
+
+ @Override
+ public boolean processFile(@NotNull final VirtualFile virtualFile) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ ProgressManager.checkCanceled();
+ if (virtualFile.isDirectory() || !virtualFile.isValid() ||
+ !myFileMask.value(virtualFile) ||
+ (globalCustomScope != null && !globalCustomScope.contains(virtualFile))) {
+ return;
+ }
+
+ if (skipIndexed && isCoveredByIdIndex(virtualFile)) {
+ return;
+ }
+
+ PsiFile psiFile = myPsiManager.findFile(virtualFile);
+ if (psiFile != null && !(psiFile instanceof PsiBinaryFile) && !alreadySearched.contains(psiFile)) {
+ PsiFile sourceFile = (PsiFile)psiFile.getNavigationElement();
+ if (sourceFile != null) psiFile = sourceFile;
+ myFiles.add(psiFile);
+ }
+ }
+ });
+ return true;
+ }
+
+ @NotNull
+ private Collection<PsiFile> getFiles() {
+ return myFiles;
+ }
+ }
+
+ EnumContentIterator iterator = new EnumContentIterator();
+
+ if (customScope instanceof LocalSearchScope) {
+ for (VirtualFile file : getLocalScopeFiles((LocalSearchScope)customScope)) {
+ iterator.processFile(file);
+ }
+ }
+ else if (myPsiDirectory != null) {
+ myFileIndex.iterateContentUnderDirectory(myPsiDirectory.getVirtualFile(), iterator);
+ }
+ else {
+ boolean success = myFileIndex.iterateContent(iterator);
+ if (success && globalCustomScope != null && globalCustomScope.isSearchInLibraries()) {
+ final VirtualFile[] librarySources = ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile[]>() {
+ @Override
+ public VirtualFile[] compute() {
+ OrderEnumerator enumerator = myModule == null ? OrderEnumerator.orderEntries(myProject) : OrderEnumerator.orderEntries(myModule);
+ return enumerator.withoutModuleSourceEntries().withoutDepModules().getSourceRoots();
+ }
+ });
+ iterateAll(librarySources, globalCustomScope, iterator);
+ }
+ }
+ return iterator.getFiles();
+ }
+
+ private static boolean isCoveredByIdIndex(VirtualFile file) {
+ return IdIndex.isIndexable(FileBasedIndexImpl.getFileType(file)) &&
+ ((FileBasedIndexImpl)FileBasedIndex.getInstance()).isIndexingCandidate(file, IdIndex.NAME);
+ }
+
+ private static boolean iterateAll(@NotNull VirtualFile[] files, @NotNull final GlobalSearchScope searchScope, @NotNull final ContentIterator iterator) {
+ final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+ final VirtualFileFilter contentFilter = new VirtualFileFilter() {
+ @Override
+ public boolean accept(@NotNull final VirtualFile file) {
+ return file.isDirectory() ||
+ !fileTypeManager.isFileIgnored(file) && !file.getFileType().isBinary() && searchScope.contains(file);
+ }
+ };
+ for (VirtualFile file : files) {
+ if (!VfsUtilCore.iterateChildrenRecursively(file, contentFilter, iterator)) return false;
+ }
+ return true;
+ }
+
+ @Nullable
+ private GlobalSearchScope toGlobal(@Nullable final SearchScope scope) {
+ if (scope instanceof GlobalSearchScope || scope == null) {
+ return (GlobalSearchScope)scope;
+ }
+ return ApplicationManager.getApplication().runReadAction(new Computable<GlobalSearchScope>() {
+ @Override
+ public GlobalSearchScope compute() {
+ return GlobalSearchScope.filesScope(myProject, getLocalScopeFiles((LocalSearchScope)scope));
+ }
+ });
+ }
+
+ @NotNull
+ private static Set<VirtualFile> getLocalScopeFiles(@NotNull LocalSearchScope scope) {
+ Set<VirtualFile> files = new LinkedHashSet<VirtualFile>();
+ for (PsiElement element : scope.getScope()) {
+ PsiFile file = element.getContainingFile();
+ if (file != null) {
+ ContainerUtil.addIfNotNull(files, file.getVirtualFile());
+ }
+ }
+ return files;
+ }
+
+ private boolean canRelyOnIndices() {
+ if (DumbService.isDumb(myProject)) return false;
+
+ if (myFindModel.isRegularExpressions()) return false;
+
+ // a local scope may be over a non-indexed file
+ if (myFindModel.getCustomScope() instanceof LocalSearchScope) return false;
+
+ String text = myFindModel.getStringToFind();
+ if (StringUtil.isEmptyOrSpaces(text)) return false;
+
+ if (TrigramIndex.ENABLED) return !TrigramBuilder.buildTrigram(text).isEmpty();
+
+ // $ is used to separate words when indexing plain-text files but not when indexing
+ // Java identifiers, so we can't consistently break a string containing $ characters into words
+
+ return myFindModel.isWholeWordsOnly() && text.indexOf('$') < 0;
+ }
+
+
+ @NotNull
+ private Set<PsiFile> getFilesForFastWordSearch() {
+ String stringToFind = myFindModel.getStringToFind();
+ if (stringToFind.isEmpty() || DumbService.getInstance(myProject).isDumb()) {
+ return Collections.emptySet();
+ }
+
+ SearchScope customScope = myFindModel.getCustomScope();
+ GlobalSearchScope scope = myPsiDirectory != null
+ ? GlobalSearchScopesCore.directoryScope(myPsiDirectory, true)
+ : myModule != null
+ ? myModule.getModuleContentScope()
+ : customScope instanceof GlobalSearchScope
+ ? (GlobalSearchScope)customScope
+ : toGlobal(customScope);
+ if (scope == null) {
+ scope = ProjectScope.getContentScope(myProject);
+ }
+
+ final Set<PsiFile> resultFiles = new LinkedHashSet<PsiFile>();
+
+ if (TrigramIndex.ENABLED) {
+ Set<Integer> keys = ContainerUtil.newTroveSet();
+ TIntHashSet trigrams = TrigramBuilder.buildTrigram(stringToFind);
+ TIntIterator it = trigrams.iterator();
+ while (it.hasNext()) {
+ keys.add(it.next());
+ }
+
+ if (!keys.isEmpty()) {
+ List<VirtualFile> hits = new ArrayList<VirtualFile>();
+ FileBasedIndex.getInstance().getFilesWithKey(TrigramIndex.INDEX_ID, keys, new CommonProcessors.CollectProcessor<VirtualFile>(hits), scope);
+
+ for (VirtualFile hit : hits) {
+ if (myFileMask.value(hit)) {
+ resultFiles.add(findFile(hit));
+ }
+ }
+
+ return resultFiles;
+ }
+ }
+
+ PsiSearchHelperImpl helper = (PsiSearchHelperImpl)PsiSearchHelper.SERVICE.getInstance(myProject);
+ helper.processFilesWithText(scope, UsageSearchContext.ANY, myFindModel.isCaseSensitive(), stringToFind, new Processor<VirtualFile>() {
+ @Override
+ public boolean process(VirtualFile file) {
+ if (myFileMask.value(file)) {
+ ContainerUtil.addIfNotNull(resultFiles, findFile(file));
+ }
+ return true;
+ }
+ });
+
+ // in case our word splitting is incorrect
+ for (PsiFile file : CacheManager.SERVICE.getInstance(myProject)
+ .getFilesWithWord(stringToFind, UsageSearchContext.ANY, scope, myFindModel.isCaseSensitive())) {
+ if (myFileMask.value(file.getVirtualFile())) {
+ resultFiles.add(file);
+ }
+ }
+
+ return resultFiles;
+ }
+
+ private PsiFile findFile(@NotNull final VirtualFile virtualFile) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
+ @Override
+ public PsiFile compute() {
+ return myPsiManager.findFile(virtualFile);
+ }
+ });
+ }
+
+}
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 2fefcc9649d4..d788d9c6abe9 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java
@@ -19,73 +19,54 @@ package com.intellij.find.impl;
import com.intellij.BundleBase;
import com.intellij.find.*;
import com.intellij.find.findInProject.FindInProjectManager;
-import com.intellij.find.ngrams.TrigramIndex;
import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditor;
-import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProcessCanceledException;
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.DumbService;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectCoreUtil;
-import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Factory;
-import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.util.text.TrigramBuilder;
-import com.intellij.openapi.vfs.*;
+import com.intellij.openapi.vfs.LocalFileProvider;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.ex.VirtualFileManagerEx;
import com.intellij.psi.*;
-import com.intellij.psi.impl.cache.CacheManager;
-import com.intellij.psi.impl.cache.impl.id.IdIndex;
-import com.intellij.psi.search.*;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.search.SearchScope;
import com.intellij.ui.content.Content;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewManager;
import com.intellij.usages.ConfigurableUsageTarget;
import com.intellij.usages.FindUsagesProcessPresentation;
-import com.intellij.usages.UsageLimitUtil;
import com.intellij.usages.UsageViewPresentation;
-import com.intellij.usages.impl.UsageViewManagerImpl;
-import com.intellij.util.CommonProcessors;
import com.intellij.util.Function;
import com.intellij.util.PatternUtil;
import com.intellij.util.Processor;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.indexing.FileBasedIndex;
-import com.intellij.util.indexing.FileBasedIndexImpl;
-import gnu.trove.THashSet;
-import gnu.trove.TIntHashSet;
-import gnu.trove.TIntIterator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
-import java.util.*;
+import java.util.List;
import java.util.regex.Pattern;
public class FindInProjectUtil {
private static final int USAGES_PER_READ_ACTION = 100;
- private static final int FILES_SIZE_LIMIT = 70 * 1024 * 1024; // megabytes.
- private static final int SINGLE_FILE_SIZE_LIMIT = 5 * 1024 * 1024; // megabytes.
private FindInProjectUtil() {}
@@ -156,34 +137,6 @@ public class FindInProjectUtil {
return virtualFile == null ? null : psiManager.findDirectory(virtualFile);
}
- private static void addFilesUnderDirectory(@NotNull PsiDirectory directory,
- @NotNull Collection<PsiFile> fileList,
- boolean isRecursive,
- @Nullable Pattern fileMaskRegExp) {
- final PsiElement[] children = directory.getChildren();
-
- for (PsiElement child : children) {
- if (child instanceof PsiFile &&
- (fileMaskRegExp == null ||
- fileMaskRegExp.matcher(((PsiFile)child).getName()).matches()
- )
- ) {
- PsiFile file = (PsiFile)child;
- PsiFile sourceFile = (PsiFile)file.getNavigationElement();
- if (sourceFile != null) file = sourceFile;
- fileList.add(file);
- }
- else if (isRecursive && child instanceof PsiDirectory) {
- addFilesUnderDirectory((PsiDirectory)child, fileList, isRecursive, fileMaskRegExp);
- }
- }
- }
-
- @Nullable
- private static Pattern createFileMaskRegExp(@NotNull FindModel findModel) {
- final String filter = findModel.getFileFilter();
- return createFileMaskRegExp(filter);
- }
@Nullable
public static Pattern createFileMaskRegExp(@Nullable String filter) {
@@ -210,74 +163,12 @@ public class FindInProjectUtil {
public static void findUsages(@NotNull FindModel findModel,
final PsiDirectory psiDirectory,
@NotNull final Project project,
- boolean showWarnings,
@NotNull final Processor<UsageInfo> consumer,
@NotNull FindUsagesProcessPresentation processPresentation) {
- final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
-
- final Collection<PsiFile> psiFiles = getFilesToSearchIn(findModel, project, psiDirectory);
- try {
- final Set<PsiFile> largeFiles = new THashSet<PsiFile>();
-
- int i = 0;
- long totalFilesSize = 0;
- int count = 0;
- final boolean[] warningShown = {false};
-
- for (final PsiFile psiFile : psiFiles) {
- final VirtualFile virtualFile = psiFile.getVirtualFile();
- final int index = i++;
- if (virtualFile == null) continue;
-
- long fileLength = UsageViewManagerImpl.getFileLength(virtualFile);
- if (fileLength == -1) continue; // Binary or invalid
-
- if (ProjectCoreUtil.isProjectOrWorkspaceFile(virtualFile) && !Registry.is("find.search.in.project.files")) continue;
-
- if (fileLength > SINGLE_FILE_SIZE_LIMIT) {
- largeFiles.add(psiFile);
- continue;
- }
-
- if (progress != null) {
- progress.checkCanceled();
- progress.setFraction((double)index / psiFiles.size());
- String text = FindBundle.message("find.searching.for.string.in.file.progress",
- findModel.getStringToFind(), virtualFile.getPresentableUrl());
- progress.setText(text);
- progress.setText2(FindBundle.message("find.searching.for.string.in.file.occurrences.progress", count));
- }
-
- int countInFile = processUsagesInFile(psiFile, findModel, consumer);
-
- count += countInFile;
- if (countInFile > 0) {
- totalFilesSize += fileLength;
- if (totalFilesSize > FILES_SIZE_LIMIT && !warningShown[0]) {
- warningShown[0] = true;
- String message = FindBundle.message("find.excessive.total.size.prompt",
- UsageViewManagerImpl.presentableSize(totalFilesSize),
- ApplicationNamesInfo.getInstance().getProductName());
- UsageLimitUtil.showAndCancelIfAborted(project, message, processPresentation.getUsageViewPresentation());
- }
- }
- }
-
-
- if (!largeFiles.isEmpty()) {
- processPresentation.setLargeFilesWereNotScanned(largeFiles);
- }
- }
- catch (ProcessCanceledException e) {
- // fine
- }
-
- if (progress != null && !progress.isCanceled()) {
- progress.setText(FindBundle.message("find.progress.search.completed"));
- }
+ new FindInProjectTask(findModel, project, psiDirectory).findUsages(consumer, processPresentation);
}
- private static int processUsagesInFile(@NotNull final PsiFile psiFile,
+ static int processUsagesInFile(@NotNull final PsiFile psiFile,
@NotNull final FindModel findModel,
@NotNull final Processor<UsageInfo> consumer) {
if (findModel.getStringToFind().isEmpty()) {
@@ -317,279 +208,6 @@ public class FindInProjectUtil {
return count;
}
- private static PsiFile findFile(@NotNull final PsiManager psiManager, @NotNull final VirtualFile virtualFile) {
- return ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
- @Override
- public PsiFile compute() {
- return psiManager.findFile(virtualFile);
- }
- });
- }
-
- @NotNull
- private static Collection<PsiFile> getFilesToSearchIn(@NotNull final FindModel findModel,
- @NotNull final Project project,
- final PsiDirectory psiDirectory) {
- final String moduleName = findModel.getModuleName();
- final Module module = moduleName == null ? null : ApplicationManager.getApplication().runReadAction(new Computable<Module>() {
- @Override
- public Module compute() {
- return ModuleManager.getInstance(project).findModuleByName(moduleName);
- }
- });
- final FileIndex fileIndex = module == null ?
- ProjectRootManager.getInstance(project).getFileIndex() :
- ModuleRootManager.getInstance(module).getFileIndex();
-
- if (psiDirectory == null || findModel.isWithSubdirectories() && fileIndex.isInContent(psiDirectory.getVirtualFile())) {
- final Pattern fileMaskRegExp = createFileMaskRegExp(findModel);
- // optimization
- Pair<Boolean, Collection<PsiFile>> fastWords = getFilesForFastWordSearch(findModel, project, psiDirectory, fileMaskRegExp, module, fileIndex);
- final Collection<PsiFile> filesForFastWordSearch = fastWords.getSecond();
-
- final boolean useIdIndex = fastWords.getFirst() && canOptimizeForFastWordSearch(findModel);
-
- SearchScope customScope = findModel.getCustomScope();
- final GlobalSearchScope globalCustomScope = toGlobal(project, customScope);
-
- class EnumContentIterator implements ContentIterator {
- final Set<PsiFile> myFiles = new LinkedHashSet<PsiFile>(filesForFastWordSearch);
- final PsiManager psiManager = PsiManager.getInstance(project);
-
- @Override
- public boolean processFile(@NotNull VirtualFile virtualFile) {
- ProgressManager.checkCanceled();
- if (virtualFile.isDirectory() ||
- (fileMaskRegExp != null && !fileMaskRegExp.matcher(virtualFile.getName()).matches()) ||
- (globalCustomScope != null && !globalCustomScope.contains(virtualFile))) {
- return true;
- }
-
- if (useIdIndex && isCoveredByIdIndex(virtualFile)) {
- return true;
- }
-
- PsiFile psiFile = findFile(psiManager, virtualFile);
- if (psiFile != null && !(psiFile instanceof PsiBinaryFile)) {
- myFiles.add(psiFile);
- }
- return true;
- }
-
- @NotNull
- private Collection<PsiFile> getFiles() {
- return myFiles;
- }
- }
-
- EnumContentIterator iterator = new EnumContentIterator();
-
- if (customScope instanceof LocalSearchScope) {
- for (VirtualFile file : getLocalScopeFiles((LocalSearchScope)customScope)) {
- iterator.processFile(file);
- }
- }
-
- if (psiDirectory == null) {
- boolean success = fileIndex.iterateContent(iterator);
- if (success && globalCustomScope != null && globalCustomScope.isSearchInLibraries()) {
- final VirtualFile[] librarySources = ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile[]>() {
- @Override
- public VirtualFile[] compute() {
- OrderEnumerator enumerator = module == null ? OrderEnumerator.orderEntries(project) : OrderEnumerator.orderEntries(module);
- return enumerator.withoutModuleSourceEntries().withoutDepModules().getSourceRoots();
- }
- });
- iterateAll(librarySources, globalCustomScope, iterator);
- }
- }
- else {
- fileIndex.iterateContentUnderDirectory(psiDirectory.getVirtualFile(), iterator);
- }
- return iterator.getFiles();
- }
- if (psiDirectory.isValid()) {
- final Collection<PsiFile> fileList = new THashSet<PsiFile>();
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- @Override
- public void run() {
- addFilesUnderDirectory(psiDirectory, fileList, findModel.isWithSubdirectories(), createFileMaskRegExp(findModel));
- }
- });
-
- return fileList;
- }
- return Collections.emptyList();
- }
-
- private static boolean isCoveredByIdIndex(VirtualFile file) {
- return IdIndex.isIndexable(FileBasedIndexImpl.getFileType(file)) &&
- ((FileBasedIndexImpl)FileBasedIndex.getInstance()).isIndexingCandidate(file, IdIndex.NAME);
- }
-
- private static boolean iterateAll(@NotNull VirtualFile[] files, @NotNull final GlobalSearchScope searchScope, @NotNull final ContentIterator iterator) {
- final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
- final VirtualFileFilter contentFilter = new VirtualFileFilter() {
- @Override
- public boolean accept(@NotNull final VirtualFile file) {
- return file.isDirectory() ||
- !fileTypeManager.isFileIgnored(file) && !file.getFileType().isBinary() && searchScope.contains(file);
- }
- };
- for (VirtualFile file : files) {
- if (!VfsUtilCore.iterateChildrenRecursively(file, contentFilter, iterator)) return false;
- }
- return true;
- }
-
- @Nullable
- private static GlobalSearchScope toGlobal(@NotNull final Project project, @Nullable final SearchScope scope) {
- if (scope instanceof GlobalSearchScope || scope == null) {
- return (GlobalSearchScope)scope;
- }
- return ApplicationManager.getApplication().runReadAction(new Computable<GlobalSearchScope>() {
- @Override
- public GlobalSearchScope compute() {
- return GlobalSearchScope.filesScope(project, getLocalScopeFiles((LocalSearchScope)scope));
- }
- });
- }
-
- @NotNull
- private static Set<VirtualFile> getLocalScopeFiles(@NotNull LocalSearchScope scope) {
- Set<VirtualFile> files = new LinkedHashSet<VirtualFile>();
- for (PsiElement element : scope.getScope()) {
- PsiFile file = element.getContainingFile();
- if (file != null) {
- ContainerUtil.addIfNotNull(files, file.getVirtualFile());
- }
- }
- return files;
- }
-
- @NotNull
- private static Pair<Boolean, Collection<PsiFile>> getFilesForFastWordSearch(@NotNull final FindModel findModel,
- @NotNull final Project project,
- @Nullable final PsiDirectory psiDirectory,
- final Pattern fileMaskRegExp,
- @Nullable final Module module,
- @NotNull FileIndex fileIndex) {
- if (DumbService.getInstance(project).isDumb()) {
- return new Pair<Boolean, Collection<PsiFile>>(false, Collections.<PsiFile>emptyList());
- }
-
- final PsiManager pm = PsiManager.getInstance(project);
- CacheManager cacheManager = CacheManager.SERVICE.getInstance(project);
- SearchScope customScope = findModel.getCustomScope();
- GlobalSearchScope scope = psiDirectory != null
- ? GlobalSearchScopesCore.directoryScope(psiDirectory, true)
- : module != null
- ? module.getModuleContentScope()
- : customScope instanceof GlobalSearchScope
- ? (GlobalSearchScope)customScope
- : toGlobal(project, customScope);
- if (scope == null) {
- scope = ProjectScope.getContentScope(project);
- }
-
- Set<Integer> keys = new THashSet<Integer>(30);
- final Set<PsiFile> resultFiles = new THashSet<PsiFile>();
- boolean fast = false;
-
- String stringToFind = findModel.getStringToFind();
- if (TrigramIndex.ENABLED) {
- TIntHashSet trigrams = TrigramBuilder.buildTrigram(stringToFind);
- TIntIterator it = trigrams.iterator();
- while (it.hasNext()) {
- keys.add(it.next());
- }
-
- if (!keys.isEmpty()) {
- fast = true;
- List<VirtualFile> hits = new ArrayList<VirtualFile>();
- FileBasedIndex.getInstance().getFilesWithKey(TrigramIndex.INDEX_ID, keys, new CommonProcessors.CollectProcessor<VirtualFile>(hits), scope);
-
- for (VirtualFile hit : hits) {
- resultFiles.add(findFile(pm, hit));
- }
-
- filterMaskedFiles(resultFiles, fileMaskRegExp);
- if (resultFiles.isEmpty()) return new Pair<Boolean, Collection<PsiFile>>(true, resultFiles);
- }
- }
-
-
- // $ is used to separate words when indexing plain-text files but not when indexing
- // Java identifiers, so we can't consistently break a string containing $ characters into words
-
- fast |= findModel.isWholeWordsOnly() && stringToFind.indexOf('$') < 0;
-
- List<String> words = StringUtil.getWordsInStringLongestFirst(stringToFind);
-
- for (int i = 0; i < words.size(); i++) {
- String word = words.get(i);
-
- PsiFile[] files = cacheManager.getFilesWithWord(word, UsageSearchContext.ANY, scope, findModel.isCaseSensitive());
- if (files.length == 0) {
- resultFiles.clear();
- break;
- }
-
- final List<PsiFile> psiFiles = Arrays.asList(files);
-
- if (i == 0 && keys.isEmpty()) {
- resultFiles.addAll(psiFiles);
- }
- else {
- resultFiles.retainAll(psiFiles);
- }
-
- filterMaskedFiles(resultFiles, fileMaskRegExp);
- if (resultFiles.isEmpty()) break;
- }
-
- if (stringToFind.isEmpty()) {
- fileIndex.iterateContent(new ContentIterator() {
- @Override
- public boolean processFile(VirtualFile file) {
- if (!file.isDirectory() && fileMaskRegExp.matcher(file.getName()).matches()) {
- PsiFile psiFile = findFile(pm, file);
- if (psiFile != null) {
- resultFiles.add(psiFile);
- }
- }
- return true;
- }
- });
- }
- else {
- // in case our word splitting is incorrect
- PsiFile[] allWordsFiles =
- cacheManager.getFilesWithWord(stringToFind, UsageSearchContext.ANY, scope, findModel.isCaseSensitive());
- ContainerUtil.addAll(resultFiles, allWordsFiles);
-
- filterMaskedFiles(resultFiles, fileMaskRegExp);
- }
-
- return new Pair<Boolean, Collection<PsiFile>>(fast, resultFiles);
- }
-
- private static void filterMaskedFiles(@NotNull final Set<PsiFile> resultFiles, @Nullable final Pattern fileMaskRegExp) {
- if (fileMaskRegExp != null) {
- for (Iterator<PsiFile> iterator = resultFiles.iterator(); iterator.hasNext();) {
- PsiFile file = iterator.next();
- if (!fileMaskRegExp.matcher(file.getName()).matches()) {
- iterator.remove();
- }
- }
- }
- }
-
- private static boolean canOptimizeForFastWordSearch(@NotNull final FindModel findModel) {
- return !findModel.isRegularExpressions()
- && (findModel.getCustomScope() == null || findModel.getCustomScope() instanceof GlobalSearchScope);
- }
-
private static int addToUsages(@NotNull Document document, @NotNull Processor<UsageInfo> consumer, @NotNull FindModel findModel,
@NotNull final PsiFile psiFile, @NotNull int[] offsetRef, int maxUsages) {
int count = 0;
diff --git a/platform/lang-impl/src/com/intellij/find/ngrams/TrigramIndex.java b/platform/lang-impl/src/com/intellij/find/ngrams/TrigramIndex.java
index 9fdc87e70686..6cf661d2cc6f 100644
--- a/platform/lang-impl/src/com/intellij/find/ngrams/TrigramIndex.java
+++ b/platform/lang-impl/src/com/intellij/find/ngrams/TrigramIndex.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,13 +38,13 @@ public class TrigramIndex extends ScalarIndexExtension<Integer> {
private static final FileBasedIndex.InputFilter INPUT_FILTER = new FileBasedIndex.InputFilter() {
@Override
- public boolean acceptInput(VirtualFile file) {
+ public boolean acceptInput(@NotNull VirtualFile file) {
return !file.getFileType().isBinary();
}
};
private static final FileBasedIndex.InputFilter NO_FILES = new FileBasedIndex.InputFilter() {
@Override
- public boolean acceptInput(VirtualFile file) {
+ public boolean acceptInput(@NotNull VirtualFile file) {
return false;
}
};
@@ -76,11 +76,13 @@ public class TrigramIndex extends ScalarIndexExtension<Integer> {
};
}
+ @NotNull
@Override
public KeyDescriptor<Integer> getKeyDescriptor() {
return EnumeratorIntegerDescriptor.INSTANCE;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
if (ENABLED) {
diff --git a/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java b/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java
index 86fe9de9b5a8..7e220c149369 100644
--- a/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java
+++ b/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java
@@ -569,7 +569,7 @@ public class ReplaceInProjectManager {
myIsFindInProgress = true;
FindInProjectUtil.findUsages(myFindModelCopy, myPsiDirectory, myProject,
- true, new AdapterProcessor<UsageInfo, Usage>(processor, UsageInfo2UsageAdapter.CONVERTER),
+ new AdapterProcessor<UsageInfo, Usage>(processor, UsageInfo2UsageAdapter.CONVERTER),
myProcessPresentation);
}
finally {
diff --git a/platform/lang-impl/src/com/intellij/framework/detection/impl/DetectedFrameworksData.java b/platform/lang-impl/src/com/intellij/framework/detection/impl/DetectedFrameworksData.java
index 0985d6b43171..dfd6c9c93548 100644
--- a/platform/lang-impl/src/com/intellij/framework/detection/impl/DetectedFrameworksData.java
+++ b/platform/lang-impl/src/com/intellij/framework/detection/impl/DetectedFrameworksData.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.
@@ -141,7 +141,7 @@ public class DetectedFrameworksData {
private static class TIntHashSetExternalizer implements DataExternalizer<TIntHashSet> {
@Override
- public void save(DataOutput out, TIntHashSet value) throws IOException {
+ public void save(@NotNull DataOutput out, TIntHashSet value) throws IOException {
out.writeInt(value.size());
final TIntIterator iterator = value.iterator();
while (iterator.hasNext()) {
@@ -150,7 +150,7 @@ public class DetectedFrameworksData {
}
@Override
- public TIntHashSet read(DataInput in) throws IOException {
+ public TIntHashSet read(@NotNull DataInput in) throws IOException {
int size = in.readInt();
final TIntHashSet set = new TIntHashSet(size);
while (size-- > 0) {
diff --git a/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionIndex.java b/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionIndex.java
index bc6eba2bba2c..514f0777a638 100644
--- a/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionIndex.java
+++ b/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionIndex.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,11 +91,13 @@ public class FrameworkDetectionIndex extends ScalarIndexExtension<Integer> {
};
}
+ @NotNull
@Override
public KeyDescriptor<Integer> getKeyDescriptor() {
return EnumeratorIntegerDescriptor.INSTANCE;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
final Set<FileType> acceptedTypes = new HashSet<FileType>();
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SaveAsAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SaveAsAction.java
index 07eee5583fb8..410eb95e6baa 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SaveAsAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SaveAsAction.java
@@ -1,9 +1,9 @@
package com.intellij.ide.actions;
+import com.intellij.ide.util.PlatformPackageUtil;
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.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -28,6 +28,6 @@ public class SaveAsAction extends DumbAwareAction {
final VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext);
@SuppressWarnings({"ConstantConditions"}) final PsiElement element = PsiManager.getInstance(project).findFile(virtualFile);
if(element==null) return;
- CopyHandler.doCopy(new PsiElement[] {element.getContainingFile()}, element.getContainingFile().getContainingDirectory());
+ CopyHandler.doCopy(new PsiElement[] {element.getContainingFile()}, PlatformPackageUtil.getDirectory(element));
}
}
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 4dcdfe826e98..a0e5608654b7 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
@@ -143,7 +143,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
private TitleIndexes myTitleIndexes;
private Map<String, String> myConfigurables = new HashMap<String, String>();
- private Alarm myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, ApplicationManager.getApplication());
+ private Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, ApplicationManager.getApplication());
private Alarm myUpdateAlarm = new Alarm(ApplicationManager.getApplication());
private JBList myList;
private JCheckBox myNonProjectCheckBox;
@@ -608,6 +608,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
private void rebuildList(final String pattern) {
+ assert EventQueue.isDispatchThread() : "Must be EDT";
if (myCalcThread != null && !myCurrentWorker.isProcessed()) {
myCurrentWorker = myCalcThread.cancel();
}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
index c7a81cbd0cda..f9d4a757f8a7 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
@@ -189,7 +189,7 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo
private final SplitterProportionsData splitterProportions = new SplitterProportionsDataImpl();
private final MessageBusConnection myConnection;
private final Map<String, Element> myUninitializedPaneState = new HashMap<String, Element>();
- private final Map<String, SelectInTarget> mySelectInTargets = new HashMap<String, SelectInTarget>();
+ private final Map<String, SelectInTarget> mySelectInTargets = new LinkedHashMap<String, SelectInTarget>();
private ContentManager myContentManager;
private boolean myFoldersAlwaysOnTop = true;
diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/CreateScratchFileAction.java b/platform/lang-impl/src/com/intellij/ide/scratch/CreateScratchFileAction.java
new file mode 100644
index 000000000000..a829cf85594f
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/scratch/CreateScratchFileAction.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.lang.Language;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.ComboBox;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.CollectionComboBoxModel;
+import com.intellij.ui.ComboboxSpeedSearch;
+import com.intellij.ui.ListCellRendererWrapper;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author ignatov
+ */
+public class CreateScratchFileAction extends AnAction implements DumbAware {
+ private static final Set<String> FORBIDDEN_LANGUAGES = ContainerUtil.newHashSet("<Generic>", "$XSLT");
+
+ public CreateScratchFileAction() {
+ super("Create Scratch File...", "New Scratch File", null);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final Project project = e.getProject();
+ if (project == null) return;
+
+ MyDialog dialog = new MyDialog(project);
+ dialog.setResizable(false);
+ if (dialog.showAndGet()) {
+ Language language = dialog.getType();
+ VirtualFile file = ScratchpadManager.getInstance(project).createScratchFile(language);
+ if (file == null) return;
+ OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file);
+ FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
+ }
+ }
+
+ private static class MyDialog extends DialogWrapper {
+ @Nullable private Project myProject;
+ @NotNull private JComboBox myComboBox;
+
+ protected MyDialog(@Nullable Project project) {
+ super(project);
+ myProject = project;
+ setTitle("Specify the Language");
+ init();
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createCenterPanel() {
+ JPanel panel = new JPanel(new BorderLayout());
+ myComboBox = createCombo(getLanguages());
+ panel.add(myComboBox, BorderLayout.CENTER);
+ return panel;
+ }
+
+ @NotNull
+ public Language getType() {
+ return ((Language)myComboBox.getSelectedItem());
+ }
+
+ @NotNull
+ private JComboBox createCombo(@NotNull List<Language> languages) {
+ JComboBox jComboBox = new ComboBox(new CollectionComboBoxModel(languages));
+ jComboBox.setRenderer(new ListCellRendererWrapper<Language>() {
+ @Override
+ public void customize(JList list, Language lang, int index, boolean selected, boolean hasFocus) {
+ if (lang != null) {
+ setText(lang.getDisplayName());
+ LanguageFileType associatedLanguage = lang.getAssociatedFileType();
+ if (associatedLanguage != null) setIcon(associatedLanguage.getIcon());
+ }
+ }
+ });
+ new ComboboxSpeedSearch(jComboBox) {
+ @Override
+ protected String getElementText(Object element) {
+ return element instanceof Language ? ((Language)element).getDisplayName() : null;
+ }
+ };
+ Language previous = myProject != null ? ScratchpadManager.getInstance(myProject).getLatestLanguage() : null;
+ if (previous != null) {
+ jComboBox.setSelectedItem(previous);
+ }
+
+ return jComboBox;
+ }
+
+ @Nullable
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myComboBox;
+ }
+ }
+
+ @NotNull
+ private static List<Language> getLanguages() {
+ Set<Language> result = ContainerUtil.newTreeSet(new Comparator<Language>() {
+ @Override
+ public int compare(Language l1, Language l2) {
+ return l1.getDisplayName().compareTo(l2.getDisplayName());
+ }
+ });
+ for (Language lang : Language.getRegisteredLanguages()) {
+ if (!StringUtil.isEmpty(lang.getDisplayName())) result.add(lang);
+ for (Language dialect : lang.getDialects()) result.add(dialect);
+ }
+ return ContainerUtil.filter(result, new Condition<Language>() {
+ @Override
+ public boolean value(Language lang) {
+ String name = lang.getDisplayName();
+ return !StringUtil.isEmpty(name) && !FORBIDDEN_LANGUAGES.contains(name);
+ }
+ });
+ }
+} \ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadFileSystem.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadFileSystem.java
new file mode 100644
index 000000000000..e643b625a7b7
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadFileSystem.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.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;
+import com.intellij.openapi.vfs.ex.dummy.DummyFileSystem;
+import com.intellij.testFramework.LightVirtualFile;
+import com.intellij.ui.LayeredIcon;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.List;
+import java.util.Map;
+
+public class ScratchpadFileSystem extends DummyFileSystem {
+ private static final String PROTOCOL = "scratchpad";
+ private final Map<String, VirtualFile> myCachedFiles = ContainerUtil.newHashMap();
+
+ public static ScratchpadFileSystem getScratchFileSystem() {
+ return (ScratchpadFileSystem)VirtualFileManager.getInstance().getFileSystem(PROTOCOL);
+ }
+
+ public void removeByPrefix(@NotNull final String prefix) {
+ List<String> toRemove = ContainerUtil.findAll(myCachedFiles.keySet(), new Condition<String>() {
+ @Override
+ public boolean value(String s) {
+ return s.startsWith(prefix);
+ }
+ });
+ for (String s : toRemove) {
+ myCachedFiles.remove(s);
+ }
+ }
+
+ @Override
+ public VirtualFile findFileByPath(@NotNull String path) {
+ VirtualFile file = myCachedFiles.get(path);
+ if (file != null && file.isValid()) return file;
+ return null;
+ }
+
+ @NotNull
+ public VirtualFile addFile(@NotNull String name, @NotNull Language language, @NotNull String prefix) {
+ VirtualFile file = new MyLightVirtualFile(name, language, prefix);
+ myCachedFiles.put(file.getPath(), file);
+ return file;
+ }
+
+ @NotNull
+ @Override
+ public String getProtocol() {
+ return PROTOCOL;
+ }
+
+ @NotNull
+ @Override
+ public String extractPresentableUrl(@NotNull String path) {
+ String substring = StringUtil.substringAfter(path, "/");
+ return substring != null ? substring : super.extractPresentableUrl(path);
+ }
+
+ @Presentation(provider = ScratchPresentation.class)
+ private static class MyLightVirtualFile extends LightVirtualFile {
+ private final String myPrefix;
+
+ public MyLightVirtualFile(@NotNull String fileName, @NotNull Language language, @NotNull String projectPrefix) {
+ super(fileName, language, "");
+ myPrefix = projectPrefix;
+ }
+
+ @NotNull
+ @Override
+ public VirtualFileSystem getFileSystem() {
+ return getScratchFileSystem();
+ }
+
+ @NotNull
+ @Override
+ public String getPath() {
+ return myPrefix + super.getPath();
+ }
+ }
+
+ public static class ScratchPresentation extends PresentationProvider<MyLightVirtualFile> {
+ @Override
+ public Icon getIcon(@NotNull MyLightVirtualFile file) {
+ return LayeredIcon.create(file.getFileType().getIcon(), AllIcons.Actions.New);
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManager.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManager.java
new file mode 100644
index 000000000000..53c988ab198f
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManager.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.ide.scratch;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class ScratchpadManager {
+ public static ScratchpadManager getInstance(@NotNull Project project) {
+ return ServiceManager.getService(project, ScratchpadManager.class);
+ }
+
+ @NotNull
+ public abstract VirtualFile createScratchFile(@NotNull Language language);
+
+ @Nullable
+ public abstract Language getLatestLanguage();
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java
new file mode 100644
index 000000000000..ed931e77f616
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.lang.Language;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+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 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 Language myLatestLanguage;
+
+ public ScratchpadManagerImpl(@NotNull Project project) {
+ myProject = project;
+ }
+
+ @NotNull
+ @Override
+ public VirtualFile createScratchFile(@NotNull final Language language) {
+ myLatestLanguage = language;
+ return ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
+ @Override
+ public VirtualFile compute() {
+ String name = generateFileName(language);
+ return ScratchpadFileSystem.getScratchFileSystem().addFile(name, language, calculatePrefix(ScratchpadManagerImpl.this.myProject));
+ }
+ });
+ }
+
+ @NotNull
+ private static String calculatePrefix(@NotNull Project project) {
+ return project.getLocationHash();
+ }
+
+ @Override
+ public Language getLatestLanguage() {
+ return myLatestLanguage;
+ }
+
+ @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;
+ }
+
+ @Override
+ public void dispose() {
+ ScratchpadFileSystem.getScratchFileSystem().removeByPrefix(calculatePrefix(myProject));
+ }
+} \ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/ide/util/PlatformPackageUtil.java b/platform/lang-impl/src/com/intellij/ide/util/PlatformPackageUtil.java
index 01ad4cb38313..30d4933cbcb4 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/PlatformPackageUtil.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/PlatformPackageUtil.java
@@ -16,7 +16,6 @@
package com.intellij.ide.util;
import com.intellij.ide.IdeBundle;
-import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
@@ -35,6 +34,7 @@ import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
+import com.intellij.psi.impl.source.resolve.FileContextUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScopes;
import com.intellij.util.*;
@@ -276,12 +276,10 @@ public class PlatformPackageUtil {
}
@Nullable
- public static PsiDirectory getDirectory(PsiElement element) {
- PsiFile file = element.getContainingFile();
- final PsiElement context = InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file);
- if (context != null) {
- file = context.getContainingFile();
- }
- return file.getParent();
+ public static PsiDirectory getDirectory(@Nullable PsiElement element) {
+ if (element == null) return null;
+ // handle injection and fragment editor
+ PsiFile file = FileContextUtil.getContextFile(element);
+ return file == null ? null : file.getContainingDirectory();
}
}
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 cee529aecccf..33b417de0af7 100644
--- a/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
+++ b/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
@@ -17,16 +17,18 @@
package com.intellij.injected.editor;
import com.intellij.openapi.editor.*;
+import com.intellij.openapi.editor.event.CaretAdapter;
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.markup.TextAttributes;
-import com.intellij.openapi.util.Segment;
-import com.intellij.openapi.util.TextRange;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
/**
* @author Alexey
@@ -102,7 +104,7 @@ public class CaretModelWindow implements CaretModel {
private final ListenerWrapperMap<CaretListener> myCaretListeners = new ListenerWrapperMap<CaretListener>();
@Override
public void addCaretListener(@NotNull final CaretListener listener) {
- CaretListener wrapper = new CaretListener() {
+ CaretListener wrapper = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
if (!myEditorWindow.getDocument().isValid()) return; // injected document can be destroyed by now
@@ -163,6 +165,11 @@ public class CaretModelWindow implements CaretModel {
return createInjectedCaret(myDelegate.getPrimaryCaret());
}
+ @Override
+ public int getCaretCount() {
+ return myDelegate.getCaretCount();
+ }
+
@NotNull
@Override
public List<Caret> getAllCarets() {
@@ -204,17 +211,14 @@ public class CaretModelWindow implements CaretModel {
}
@Override
- public void setCaretsAndSelections(@NotNull List<LogicalPosition> caretPositions, @NotNull List<? extends Segment> selections) {
- List<LogicalPosition> convertedPositions = new ArrayList<LogicalPosition>(caretPositions);
- for (LogicalPosition position : caretPositions) {
- convertedPositions.add(myEditorWindow.injectedToHost(position));
- }
- List<Segment> convertedSelections = new ArrayList<Segment>(selections.size());
- for (Segment selection : selections) {
- convertedSelections.add(new TextRange(myEditorWindow.getDocument().injectedToHost(selection.getStartOffset()),
- myEditorWindow.getDocument().injectedToHost(selection.getEndOffset())));
+ public void setCaretsAndSelections(@NotNull List<CaretState> caretStates) {
+ List<CaretState> convertedStates = new ArrayList<CaretState>(caretStates.size());
+ for (CaretState state : caretStates) {
+ convertedStates.add(new CaretState(state.getCaretPosition() == null ? null : myEditorWindow.injectedToHost(state.getCaretPosition()),
+ state.getSelectionStart() == null ? null : myEditorWindow.injectedToHost(state.getSelectionStart()),
+ state.getSelectionEnd() == null ? null : myEditorWindow.injectedToHost(state.getSelectionEnd())));
}
- myDelegate.setCaretsAndSelections(convertedPositions, convertedSelections);
+ myDelegate.setCaretsAndSelections(convertedStates);
}
private InjectedCaret createInjectedCaret(Caret caret) {
diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
index 124b5d6ca7b5..dfaa6501831b 100644
--- a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
+++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.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,7 +34,6 @@ import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataProvider;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -1211,7 +1210,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
myEditor.setHighlighter(EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, lightFile));
}
- private class EditorListener implements CaretListener, SelectionListener, DocumentListener {
+ private class EditorListener extends CaretAdapter implements SelectionListener, DocumentListener {
@Override
public void caretPositionChanged(CaretEvent e) {
if (!available() || myEditor.getSelectionModel().hasSelection()) return;
diff --git a/platform/lang-impl/src/com/intellij/openapi/diff/impl/settings/DiffPreviewPanel.java b/platform/lang-impl/src/com/intellij/openapi/diff/impl/settings/DiffPreviewPanel.java
index 9e227b0d8fe0..9e329582ddad 100644
--- a/platform/lang-impl/src/com/intellij/openapi/diff/impl/settings/DiffPreviewPanel.java
+++ b/platform/lang-impl/src/com/intellij/openapi/diff/impl/settings/DiffPreviewPanel.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.
@@ -165,6 +165,16 @@ public class DiffPreviewPanel implements PreviewPanel {
public void caretPositionChanged(CaretEvent e) {
select(MergeSearchHelper.findChangeAt(e, getMergePanel(), myIndex));
}
+
+ @Override
+ public void caretAdded(CaretEvent e) {
+
+ }
+
+ @Override
+ public void caretRemoved(CaretEvent e) {
+
+ }
}
@Override
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
new file mode 100644
index 000000000000..81965ba9436d
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectAllOccurrencesAction.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.actions;
+
+import com.intellij.find.FindManager;
+import com.intellij.find.FindModel;
+import com.intellij.find.FindResult;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.editor.Caret;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.ScrollType;
+import com.intellij.openapi.editor.actionSystem.EditorAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.Nullable;
+
+public class SelectAllOccurrencesAction extends EditorAction {
+ protected SelectAllOccurrencesAction() {
+ super(new Handler());
+ }
+
+ private static class Handler extends SelectOccurrencesActionHandler {
+ @Override
+ public boolean isEnabled(Editor editor, DataContext dataContext) {
+ return super.isEnabled(editor, dataContext) && editor.getProject() != null && editor.getCaretModel().supportsMultipleCarets();
+ }
+
+ @Override
+ public void execute(Editor editor, @Nullable Caret c, DataContext dataContext) {
+ Caret caret = c == null ? editor.getCaretModel().getPrimaryCaret() : c;
+
+ if (!caret.hasSelection()) {
+ TextRange wordSelectionRange = getSelectionRange(editor, caret);
+ if (wordSelectionRange != null) {
+ setSelection(editor, caret, wordSelectionRange);
+ }
+ }
+
+ String selectedText = caret.getSelectedText();
+ Project project = editor.getProject();
+ if (project == null || selectedText == null) {
+ return;
+ }
+
+ int caretShiftFromSelectionStart = caret.getOffset() - caret.getSelectionStart();
+ FindManager findManager = FindManager.getInstance(project);
+
+ FindModel model = new FindModel();
+ model.setStringToFind(selectedText);
+ model.setCaseSensitive(true);
+ model.setWholeWordsOnly(true);
+
+ int searchStartOffset = 0;
+ FindResult findResult = findManager.findString(editor.getDocument().getCharsSequence(), searchStartOffset, model);
+ while (findResult.isStringFound()) {
+ int newCaretOffset = caretShiftFromSelectionStart + findResult.getStartOffset();
+ EditorActionUtil.makePositionVisible(editor, newCaretOffset);
+ Caret newCaret = editor.getCaretModel().addCaret(editor.offsetToVisualPosition(newCaretOffset));
+ if (newCaret != null) {
+ setSelection(editor, newCaret, findResult);
+ }
+ findResult = findManager.findString(editor.getDocument().getCharsSequence(), findResult.getEndOffset(), model);
+ }
+ editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectNextOccurrenceAction.java b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectNextOccurrenceAction.java
index 81a7851da874..0063a9f3f6e2 100644
--- a/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectNextOccurrenceAction.java
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectNextOccurrenceAction.java
@@ -15,37 +15,24 @@
*/
package com.intellij.openapi.editor.actions;
-import com.intellij.codeInsight.editorActions.SelectWordUtil;
-import com.intellij.codeInsight.hint.HintManager;
-import com.intellij.codeInsight.hint.HintManagerImpl;
-import com.intellij.codeInsight.hint.HintUtil;
-import com.intellij.find.FindBundle;
import com.intellij.find.FindManager;
import com.intellij.find.FindModel;
import com.intellij.find.FindResult;
-import com.intellij.openapi.editor.EditorLastActionTracker;
import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.actionSystem.EditorAction;
-import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
-import com.intellij.ui.LightweightHint;
import org.jetbrains.annotations.Nullable;
public class SelectNextOccurrenceAction extends EditorAction {
- private static final Key<Boolean> NOT_FOUND = Key.create("select.next.occurence.not.found");
- private static final Key<Boolean> WHOLE_WORDS = Key.create("select.next.occurence.whole.words");
-
protected SelectNextOccurrenceAction() {
super(new Handler());
}
- static class Handler extends EditorActionHandler {
+ static class Handler extends SelectOccurrencesActionHandler {
@Override
public boolean isEnabled(Editor editor, DataContext dataContext) {
return super.isEnabled(editor, dataContext) && editor.getProject() != null && editor.getCaretModel().supportsMultipleCarets();
@@ -54,9 +41,7 @@ public class SelectNextOccurrenceAction extends EditorAction {
@Override
public void execute(Editor editor, @Nullable Caret c, DataContext dataContext) {
Caret caret = c == null ? editor.getCaretModel().getPrimaryCaret() : c;
- TextRange wordSelectionRange = SelectWordUtil.getWordSelectionRange(editor.getDocument().getCharsSequence(),
- caret.getOffset(),
- SelectWordUtil.JAVA_IDENTIFIER_PART_CONDITION);
+ TextRange wordSelectionRange = getSelectionRange(editor, caret);
boolean notFoundPreviously = getAndResetNotFoundStatus(editor);
boolean wholeWordSearch = isWholeWordSearch(editor);
if (caret.hasSelection()) {
@@ -68,7 +53,7 @@ public class SelectNextOccurrenceAction extends EditorAction {
FindManager findManager = FindManager.getInstance(project);
FindModel model = new FindModel();
- model.setStringToFind(caret.getSelectedText());
+ model.setStringToFind(selectedText);
model.setCaseSensitive(true);
model.setWholeWordsOnly(wholeWordSearch);
@@ -102,50 +87,5 @@ public class SelectNextOccurrenceAction extends EditorAction {
}
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
-
- private static void setSelection(Editor editor, Caret caret, TextRange selectionRange) {
- EditorActionUtil.makePositionVisible(editor, selectionRange.getStartOffset());
- EditorActionUtil.makePositionVisible(editor, selectionRange.getEndOffset());
- caret.setSelection(selectionRange.getStartOffset(), selectionRange.getEndOffset());
- }
-
-
- private static void showHint(final Editor editor) {
- String message = FindBundle.message("select.next.occurence.not.found.message");
- final LightweightHint hint = new LightweightHint(HintUtil.createInformationLabel(message));
- HintManagerImpl.getInstanceImpl().showEditorHint(hint,
- editor,
- HintManager.UNDER,
- HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING,
- 0,
- false);
- }
-
- static boolean getAndResetNotFoundStatus(Editor editor) {
- boolean status = editor.getUserData(NOT_FOUND) != null;
- editor.putUserData(NOT_FOUND, null);
- return status && isRepeatedActionInvocation();
- }
-
- private static void setNotFoundStatus(Editor editor) {
- editor.putUserData(NOT_FOUND, Boolean.TRUE);
- }
-
- private static boolean isWholeWordSearch(Editor editor) {
- if (!isRepeatedActionInvocation()) {
- editor.putUserData(WHOLE_WORDS, null);
- }
- Boolean value = editor.getUserData(WHOLE_WORDS);
- return value != null;
- }
-
- private static void setWholeWordSearch(Editor editor, boolean isWholeWordSearch) {
- editor.putUserData(WHOLE_WORDS, isWholeWordSearch);
- }
-
- private static boolean isRepeatedActionInvocation() {
- String lastActionId = EditorLastActionTracker.getInstance().getLastActionId();
- return IdeActions.ACTION_SELECT_NEXT_OCCURENCE.equals(lastActionId) || IdeActions.ACTION_UNSELECT_LAST_OCCURENCE.equals(lastActionId);
- }
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectOccurrencesActionHandler.java b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectOccurrencesActionHandler.java
new file mode 100644
index 000000000000..c43eae703fd5
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectOccurrencesActionHandler.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.actions;
+
+import com.intellij.codeInsight.editorActions.SelectWordUtil;
+import com.intellij.codeInsight.hint.HintManager;
+import com.intellij.codeInsight.hint.HintManagerImpl;
+import com.intellij.codeInsight.hint.HintUtil;
+import com.intellij.find.FindBundle;
+import com.intellij.openapi.actionSystem.IdeActions;
+import com.intellij.openapi.editor.Caret;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorLastActionTracker;
+import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.ui.LightweightHint;
+import org.jetbrains.annotations.Nullable;
+
+abstract public class SelectOccurrencesActionHandler extends EditorActionHandler {
+
+ private static final Key<Boolean> NOT_FOUND = Key.create("select.next.occurence.not.found");
+ private static final Key<Boolean> WHOLE_WORDS = Key.create("select.next.occurence.whole.words");
+
+ protected static void setSelection(Editor editor, Caret caret, TextRange selectionRange) {
+ EditorActionUtil.makePositionVisible(editor, selectionRange.getStartOffset());
+ EditorActionUtil.makePositionVisible(editor, selectionRange.getEndOffset());
+ caret.setSelection(selectionRange.getStartOffset(), selectionRange.getEndOffset());
+ }
+
+ protected static void showHint(final Editor editor) {
+ String message = FindBundle.message("select.next.occurence.not.found.message");
+ final LightweightHint hint = new LightweightHint(HintUtil.createInformationLabel(message));
+ HintManagerImpl.getInstanceImpl().showEditorHint(hint,
+ editor,
+ HintManager.UNDER,
+ HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING,
+ 0,
+ false);
+ }
+
+ protected static boolean getAndResetNotFoundStatus(Editor editor) {
+ boolean status = editor.getUserData(NOT_FOUND) != null;
+ editor.putUserData(NOT_FOUND, null);
+ return status && isRepeatedActionInvocation();
+ }
+
+ protected static void setNotFoundStatus(Editor editor) {
+ editor.putUserData(NOT_FOUND, Boolean.TRUE);
+ }
+
+ protected static boolean isWholeWordSearch(Editor editor) {
+ if (!isRepeatedActionInvocation()) {
+ editor.putUserData(WHOLE_WORDS, null);
+ }
+ Boolean value = editor.getUserData(WHOLE_WORDS);
+ return value != null;
+ }
+
+ @Nullable
+ protected static TextRange getSelectionRange(Editor editor, Caret caret) {
+ return SelectWordUtil.getWordSelectionRange(editor.getDocument().getCharsSequence(),
+ caret.getOffset(),
+ SelectWordUtil.JAVA_IDENTIFIER_PART_CONDITION);
+ }
+
+ protected static void setWholeWordSearch(Editor editor, boolean isWholeWordSearch) {
+ editor.putUserData(WHOLE_WORDS, isWholeWordSearch);
+ }
+
+ protected static boolean isRepeatedActionInvocation() {
+ String lastActionId = EditorLastActionTracker.getInstance().getLastActionId();
+ return IdeActions.ACTION_SELECT_NEXT_OCCURENCE.equals(lastActionId) || IdeActions.ACTION_UNSELECT_PREVIOUS_OCCURENCE.equals(lastActionId);
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/actions/UnselectLastOccurrenceAction.java b/platform/lang-impl/src/com/intellij/openapi/editor/actions/UnselectPreviousOccurrenceAction.java
index 192e41cdfdb6..489aa4e9fb86 100644
--- a/platform/lang-impl/src/com/intellij/openapi/editor/actions/UnselectLastOccurrenceAction.java
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/actions/UnselectPreviousOccurrenceAction.java
@@ -20,15 +20,14 @@ import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.actionSystem.EditorAction;
-import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import org.jetbrains.annotations.Nullable;
-public class UnselectLastOccurrenceAction extends EditorAction {
- protected UnselectLastOccurrenceAction() {
+public class UnselectPreviousOccurrenceAction extends EditorAction {
+ protected UnselectPreviousOccurrenceAction() {
super(new Handler());
}
- private static class Handler extends EditorActionHandler {
+ private static class Handler extends SelectOccurrencesActionHandler {
@Override
public boolean isEnabled(Editor editor, DataContext dataContext) {
return super.isEnabled(editor, dataContext) && editor.getCaretModel().supportsMultipleCarets();
@@ -36,13 +35,13 @@ public class UnselectLastOccurrenceAction extends EditorAction {
@Override
public void execute(Editor editor, @Nullable Caret caret, DataContext dataContext) {
- if (editor.getCaretModel().getAllCarets().size() > 1) {
+ if (editor.getCaretModel().getCaretCount() > 1) {
editor.getCaretModel().removeCaret(editor.getCaretModel().getPrimaryCaret());
}
else {
editor.getSelectionModel().removeSelection();
}
- SelectNextOccurrenceAction.Handler.getAndResetNotFoundStatus(editor);
+ getAndResetNotFoundStatus(editor);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeFactory.java b/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeFactory.java
index 4a94d1ad3781..801887614413 100644
--- a/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeFactory.java
+++ b/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeFactory.java
@@ -33,6 +33,7 @@ import javax.swing.*;
public class EnforcedPlainTextFileTypeFactory extends FileTypeFactory {
public static final LayeredIcon ENFORCED_PLAIN_TEXT_ICON = new LayeredIcon(2);
+ public static final String ENFORCED_PLAIN_TEXT = "Enforced Plain Text";
static {
ENFORCED_PLAIN_TEXT_ICON.setIcon(AllIcons.FileTypes.Text, 0);
@@ -59,13 +60,13 @@ public class EnforcedPlainTextFileTypeFactory extends FileTypeFactory {
@NotNull
@Override
public String getName() {
- return "Enforced Plain Text";
+ return ENFORCED_PLAIN_TEXT;
}
@NotNull
@Override
public String getDescription() {
- return "Enforced Plain Text";
+ return ENFORCED_PLAIN_TEXT;
}
@NotNull
diff --git a/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java b/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java
index 830681b9ba5e..e8a18e423423 100644
--- a/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java
+++ b/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java
@@ -26,9 +26,8 @@ import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerListener;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
import com.intellij.openapi.util.EmptyRunnable;
-import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.newvfs.impl.StubVirtualFile;
+import com.intellij.openapi.vfs.VirtualFileWithId;
import com.intellij.util.containers.ConcurrentHashMap;
import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.annotations.NotNull;
@@ -45,18 +44,21 @@ import java.util.Map;
*/
public class EnforcedPlainTextFileTypeManager implements ProjectManagerListener {
private final Map<Project, Collection<VirtualFile>> myPlainTextFileSets = new ConcurrentHashMap<Project, Collection<VirtualFile>>();
- private final Ref<Boolean> mySetsInitialized = new Ref<Boolean>(false);
+ private volatile boolean mySetsInitialized = false;
+ private static final Object LOCK = new Object();
public EnforcedPlainTextFileTypeManager() {
ProjectManager.getInstance().addProjectManagerListener(this);
}
public boolean isMarkedAsPlainText(VirtualFile file) {
- if (file instanceof StubVirtualFile || file.isDirectory()) return false;
- synchronized (mySetsInitialized) {
- if (!mySetsInitialized.get()) {
- initPlainTextFileSets();
- mySetsInitialized.set(true);
+ if (!(file instanceof VirtualFileWithId) || file.isDirectory()) return false;
+ if (!mySetsInitialized) {
+ synchronized (LOCK) {
+ if (!mySetsInitialized) {
+ initPlainTextFileSets();
+ mySetsInitialized = true;
+ }
}
}
for (Project project : myPlainTextFileSets.keySet()) {
@@ -74,7 +76,7 @@ public class EnforcedPlainTextFileTypeManager implements ProjectManagerListener
}
public static boolean isApplicableFor(@NotNull VirtualFile file) {
- if (file instanceof StubVirtualFile || file.isDirectory()) return false;
+ if (!(file instanceof VirtualFileWithId) || file.isDirectory()) return false;
FileType originalType = FileTypeManager.getInstance().getFileTypeByFileName(file.getName());
return !originalType.isBinary() && originalType != FileTypes.PLAIN_TEXT && originalType != StdFileTypes.JAVA;
}
@@ -96,7 +98,7 @@ public class EnforcedPlainTextFileTypeManager implements ProjectManagerListener
fireRootsChanged(filesToSync, isPlainText);
}
- private static void fireRootsChanged(final Collection<VirtualFile> files, final boolean isAdded) {
+ private void fireRootsChanged(final Collection<VirtualFile> files, final boolean isAdded) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -105,6 +107,7 @@ public class EnforcedPlainTextFileTypeManager implements ProjectManagerListener
ProjectPlainTextFileTypeManager projectPlainTextFileTypeManager = ProjectPlainTextFileTypeManager.getInstance(project);
for (VirtualFile file : files) {
if (projectPlainTextFileTypeManager.hasProjectContaining(file)) {
+ ensureProjectFileSetAdded(project, projectPlainTextFileTypeManager);
if (isAdded) {
projectPlainTextFileTypeManager.addFile(file);
}
@@ -118,6 +121,13 @@ public class EnforcedPlainTextFileTypeManager implements ProjectManagerListener
});
}
+ private void ensureProjectFileSetAdded(@NotNull Project project,
+ @NotNull ProjectPlainTextFileTypeManager projectPlainTextFileTypeManager) {
+ if (!myPlainTextFileSets.containsKey(project)) {
+ myPlainTextFileSets.put(project, projectPlainTextFileTypeManager.getFiles());
+ }
+ }
+
private static class EnforcedPlainTextFileTypeManagerHolder {
private static final EnforcedPlainTextFileTypeManager ourInstance = ServiceManager.getService(EnforcedPlainTextFileTypeManager.class);
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/file/exclude/PersistentFileSetManager.java b/platform/lang-impl/src/com/intellij/openapi/file/exclude/PersistentFileSetManager.java
index 6cf91fe5a0c0..67b19d6fa54f 100644
--- a/platform/lang-impl/src/com/intellij/openapi/file/exclude/PersistentFileSetManager.java
+++ b/platform/lang-impl/src/com/intellij/openapi/file/exclude/PersistentFileSetManager.java
@@ -19,7 +19,7 @@ import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
-import com.intellij.openapi.vfs.newvfs.impl.StubVirtualFile;
+import com.intellij.openapi.vfs.VirtualFileWithId;
import com.intellij.util.containers.HashSet;
import org.jdom.Attribute;
import org.jdom.Element;
@@ -37,7 +37,7 @@ public class PersistentFileSetManager implements PersistentStateComponent<Elemen
private final Set<VirtualFile> myFiles = new HashSet<VirtualFile>();
protected boolean addFile(VirtualFile file) {
- if (file instanceof StubVirtualFile || file.isDirectory()) return false;
+ if (!(file instanceof VirtualFileWithId) || file.isDirectory()) return false;
myFiles.add(file);
return true;
}
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 f32a372d11ed..af4484a114d7 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
@@ -262,51 +262,61 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx
return getStateStore().getOptionValue(optionName);
}
+ @NotNull
@Override
public GlobalSearchScope getModuleScope() {
return myModuleScopeProvider.getModuleScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleScope(boolean includeTests) {
return myModuleScopeProvider.getModuleScope(includeTests);
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithLibrariesScope() {
return myModuleScopeProvider.getModuleWithLibrariesScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithDependenciesScope() {
return myModuleScopeProvider.getModuleWithDependenciesScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleContentScope() {
return myModuleScopeProvider.getModuleContentScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleContentWithDependenciesScope() {
return myModuleScopeProvider.getModuleContentWithDependenciesScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithDependenciesAndLibrariesScope(boolean includeTests) {
return myModuleScopeProvider.getModuleWithDependenciesAndLibrariesScope(includeTests);
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithDependentsScope() {
return myModuleScopeProvider.getModuleWithDependentsScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleTestsWithDependentsScope() {
return myModuleScopeProvider.getModuleTestsWithDependentsScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleRuntimeScope(boolean includeTests) {
return myModuleScopeProvider.getModuleRuntimeScope(includeTests);
diff --git a/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/TodoCheckinHandlerWorker.java b/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/TodoCheckinHandlerWorker.java
index cd8c1bf76994..40e1e793a23f 100644
--- a/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/TodoCheckinHandlerWorker.java
+++ b/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/TodoCheckinHandlerWorker.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.checkin;
import com.intellij.ide.todo.TodoFilter;
import com.intellij.ide.todo.TodoIndexPatternProvider;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.ComparisonPolicy;
import com.intellij.openapi.diff.impl.fragments.LineFragment;
@@ -302,7 +303,8 @@ public class TodoCheckinHandlerWorker {
private static ArrayList<LineFragment> getLineFragments(final String fileName, String beforeContent, String afterContent) throws VcsException {
try {
- DiffFragment[] woFormattingBlocks = DiffPolicy.LINES_WO_FORMATTING.buildFragments(beforeContent, afterContent);
+ DiffFragment[] woFormattingBlocks =
+ DiffPolicy.LINES_WO_FORMATTING.buildFragments(DiffString.create(beforeContent), DiffString.create(afterContent));
DiffFragment[] step1lineFragments =
new DiffCorrection.TrueLineBlocks(ComparisonPolicy.IGNORE_SPACE).correctAndNormalize(woFormattingBlocks);
return new DiffFragmentsProcessor().process(step1lineFragments);
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeIndex.java b/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeIndex.java
index 43bc2facc8a8..bc1254ceca7a 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeIndex.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeIndex.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.
@@ -108,6 +108,7 @@ public class FileIncludeIndex extends FileBasedIndexExtension<FileIncludeIndex.K
};
}
+ @NotNull
@Override
public KeyDescriptor<Key> getKeyDescriptor() {
return new KeyDescriptor<Key>() {
@@ -122,24 +123,25 @@ public class FileIncludeIndex extends FileBasedIndexExtension<FileIncludeIndex.K
}
@Override
- public void save(DataOutput out, Key value) throws IOException {
+ public void save(@NotNull DataOutput out, Key value) throws IOException {
out.writeBoolean(value.isInclude());
value.writeValue(out);
}
@Override
- public Key read(DataInput in) throws IOException {
+ public Key read(@NotNull DataInput in) throws IOException {
boolean isInclude = in.readBoolean();
return isInclude ? IncludeKey.read(in) : new FileKey(in.readInt());
}
};
}
+ @NotNull
@Override
public DataExternalizer<List<FileIncludeInfoImpl>> getValueExternalizer() {
return new DataExternalizer<List<FileIncludeInfoImpl>>() {
@Override
- public void save(DataOutput out, List<FileIncludeInfoImpl> value) throws IOException {
+ public void save(@NotNull DataOutput out, List<FileIncludeInfoImpl> value) throws IOException {
out.writeInt(value.size());
for (FileIncludeInfoImpl info : value) {
out.writeUTF(info.path);
@@ -150,7 +152,7 @@ public class FileIncludeIndex extends FileBasedIndexExtension<FileIncludeIndex.K
}
@Override
- public List<FileIncludeInfoImpl> read(DataInput in) throws IOException {
+ public List<FileIncludeInfoImpl> read(@NotNull DataInput in) throws IOException {
int size = in.readInt();
ArrayList<FileIncludeInfoImpl> infos = new ArrayList<FileIncludeInfoImpl>(size);
for (int i = 0; i < size; i++) {
@@ -161,11 +163,12 @@ public class FileIncludeIndex extends FileBasedIndexExtension<FileIncludeIndex.K
};
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new FileBasedIndex.FileTypeSpecificInputFilter() {
@Override
- public boolean acceptInput(VirtualFile file) {
+ public boolean acceptInput(@NotNull VirtualFile file) {
if (file.getFileSystem() == JarFileSystem.getInstance()) {
return false;
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java
index 19f1aa2cd70f..8fa6c5771fdd 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java
@@ -55,6 +55,7 @@ import com.intellij.psi.injection.ReferenceInjector;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -214,16 +215,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT
Language forcedLanguage = myContextElement.getUserData(InjectedFileViewProvider.LANGUAGE_FOR_INJECTED_COPY_KEY);
myLanguage = forcedLanguage == null ? LanguageSubstitutors.INSTANCE.substituteLanguage(myLanguage, virtualFile, myProject) : forcedLanguage;
- DocumentImpl decodedDocument;
- if (StringUtil.indexOf(outChars, '\r') == -1) {
- decodedDocument = new DocumentImpl(outChars);
- }
- else {
- decodedDocument = new DocumentImpl("", true);
- decodedDocument.setAcceptSlashR(true);
- decodedDocument.replaceString(0,0,outChars);
- }
- FileDocumentManagerImpl.registerDocument(decodedDocument, virtualFile);
+ createDocument(virtualFile);
InjectedFileViewProvider viewProvider = new InjectedFileViewProvider(myPsiManager, virtualFile, documentWindow, myLanguage);
ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(myLanguage);
@@ -307,6 +299,14 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT
}
}
+ @NotNull
+ private static DocumentEx createDocument(@NotNull LightVirtualFile virtualFile) {
+ CharSequence content = virtualFile.getContent();
+ DocumentImpl document = new DocumentImpl(content, StringUtil.indexOf(content, '\r') >= 0, false);
+ FileDocumentManagerImpl.registerDocument(document, virtualFile);
+ return document;
+ }
+
// returns true if shreds were set, false if old ones were reused
private static boolean cacheEverything(@NotNull Place place,
@NotNull DocumentWindowImpl documentWindow,
diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java
index 0877a65f51bc..6682da34ed4c 100644
--- a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.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 @@
*/
package com.intellij.psi.stubs;
+import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.*;
@@ -26,12 +27,16 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.NotNullComputable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
+import com.intellij.psi.LanguageSubstitutors;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -53,7 +58,6 @@ import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.util.*;
-import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
@@ -161,7 +165,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
private static class StubIdExternalizer implements DataExternalizer<StubIdList> {
@Override
- public void save(final DataOutput out, @NotNull final StubIdList value) throws IOException {
+ public void save(@NotNull final DataOutput out, @NotNull final StubIdList value) throws IOException {
int size = value.size();
if (size == 0) {
DataInputOutputUtil.writeINT(out, Integer.MAX_VALUE);
@@ -179,7 +183,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
@NotNull
@Override
- public StubIdList read(final DataInput in) throws IOException {
+ public StubIdList read(@NotNull final DataInput in) throws IOException {
int size = DataInputOutputUtil.readINT(in);
if (size == Integer.MAX_VALUE) {
return new StubIdList();
@@ -424,9 +428,10 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
public <K> void updateIndex(@NotNull StubIndexKey key, int fileId, @NotNull final Map<K, StubIdList> oldValues, @NotNull Map<K, StubIdList> newValues) {
try {
final MyIndex<K> index = (MyIndex<K>)myIndices.get(key);
- index.updateWithMap(fileId, newValues, new Callable<Collection<K>>() {
+ index.updateWithMap(fileId, newValues, new NotNullComputable<Collection<K>>() {
+ @NotNull
@Override
- public Collection<K> call() throws Exception {
+ public Collection<K> compute() {
return oldValues.keySet();
}
});
@@ -445,7 +450,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
@Override
public void updateWithMap(final int inputId,
@NotNull final Map<K, StubIdList> newData,
- @NotNull Callable<Collection<K>> oldKeysGetter) throws StorageException {
+ @NotNull NotNullComputable<Collection<K>> oldKeysGetter) throws StorageException {
super.updateWithMap(inputId, newData, oldKeysGetter);
}
}
@@ -465,8 +470,13 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
out.printf("\nfile: %s\npsiElement: %s\nrequiredClass: %s\nactualClass: %s",
file, psi, requiredClass, psi.getClass());
- out.printf("\nvirtualFile: size:%s; stamp:%s; modCount:%s",
- file.getLength(), file.getModificationStamp(), file.getModificationCount());
+ FileType fileType = file.getFileType();
+ Language language = fileType instanceof LanguageFileType ?
+ LanguageSubstitutors.INSTANCE.substituteLanguage(((LanguageFileType)fileType).getLanguage(), file, psi.getProject()) :
+ Language.ANY;
+ out.printf("\nvirtualFile: size:%s; stamp:%s; modCount:%s; fileType:%s; language:%s",
+ file.getLength(), file.getModificationStamp(), file.getModificationCount(),
+ fileType.getName(), language.getID());
Document document = FileDocumentManager.getInstance().getCachedDocument(file);
if (document != null) {
@@ -478,8 +488,9 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
PsiFile psiFile = psi.getManager().findFile(file);
if (psiFile != null) {
- out.printf("\npsiFile: size:%s; stamp:%s; class:%s",
- psiFile.getTextLength(), psiFile.getViewProvider().getModificationStamp(), psiFile.getClass().getName());
+ out.printf("\npsiFile: size:%s; stamp:%s; class:%s; language:%s",
+ psiFile.getTextLength(), psiFile.getViewProvider().getModificationStamp(), psiFile.getClass().getName(),
+ psiFile.getLanguage().getID());
}
StubTree stub = psiFile instanceof PsiFileWithStubSupport ? ((PsiFileWithStubSupport)psiFile).getStubTree() : null;
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 93e2b3541f41..4cb07a623f03 100644
--- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java
+++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.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,6 +23,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.util.NotNullComputable;
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.FileAttribute;
@@ -37,7 +38,6 @@ import org.jetbrains.annotations.NotNull;
import java.io.*;
import java.util.*;
-import java.util.concurrent.Callable;
/*
* @author max
@@ -54,13 +54,13 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
private static final DataExternalizer<SerializedStubTree> KEY_EXTERNALIZER = new DataExternalizer<SerializedStubTree>() {
@Override
- public void save(final DataOutput out, @NotNull final SerializedStubTree v) throws IOException {
+ public void save(@NotNull final DataOutput out, @NotNull final SerializedStubTree v) throws IOException {
v.write(out);
}
@NotNull
@Override
- public SerializedStubTree read(final DataInput in) throws IOException {
+ public SerializedStubTree read(@NotNull final DataInput in) throws IOException {
return new SerializedStubTree(in);
}
};
@@ -226,11 +226,11 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
@NotNull
@Override
- public UpdatableIndex<Integer, SerializedStubTree, FileContent> createIndexImplementation(final ID<Integer, SerializedStubTree> indexId, @NotNull final FileBasedIndex owner, @NotNull IndexStorage<Integer, SerializedStubTree> storage)
+ public UpdatableIndex<Integer, SerializedStubTree, FileContent> createIndexImplementation(@NotNull final ID<Integer, SerializedStubTree> indexId, @NotNull final FileBasedIndex owner, @NotNull IndexStorage<Integer, SerializedStubTree> storage)
throws StorageException {
if (storage instanceof MemoryIndexStorage) {
final MemoryIndexStorage<Integer, SerializedStubTree> memStorage = (MemoryIndexStorage<Integer, SerializedStubTree>)storage;
- memStorage.addBufferingStateListsner(new MemoryIndexStorage.BufferingStateListener() {
+ memStorage.addBufferingStateListener(new MemoryIndexStorage.BufferingStateListener() {
@Override
public void bufferingStateChanged(final boolean newState) {
((StubIndexImpl)StubIndex.getInstance()).setDataBufferingEnabled(newState);
@@ -294,7 +294,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
@Override
protected void updateWithMap(final int inputId,
@NotNull final Map<Integer, SerializedStubTree> newData,
- @NotNull Callable<Collection<Integer>> oldKeysGetter)
+ @NotNull NotNullComputable<Collection<Integer>> oldKeysGetter)
throws StorageException {
checkNameStorage();
diff --git a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
index 773bb2b54ef6..2532a9207298 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
@@ -465,7 +465,7 @@ public abstract class BaseRefactoringProcessor implements Runnable {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
RefactoringListenerManagerImpl listenerManager = (RefactoringListenerManagerImpl)RefactoringListenerManager.getInstance(myProject);
myTransaction = listenerManager.startTransaction();
- final Map<RefactoringHelper, Object> preparedData = new HashMap<RefactoringHelper, Object>();
+ final Map<RefactoringHelper, Object> preparedData = new LinkedHashMap<RefactoringHelper, Object>();
final Runnable prepareHelpersRunnable = new Runnable() {
@Override
public void run() {
diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/MethodSignatureEditor.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/MethodSignatureEditor.java
index 83122e1cc00b..d5d4812d93da 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/MethodSignatureEditor.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/MethodSignatureEditor.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,10 +21,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.LogicalPosition;
-import com.intellij.openapi.editor.event.CaretEvent;
-import com.intellij.openapi.editor.event.CaretListener;
-import com.intellij.openapi.editor.event.DocumentAdapter;
-import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.impl.CaretModelImpl;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.util.Key;
@@ -163,7 +160,7 @@ public abstract class MethodSignatureEditor<M extends PsiElement> extends Editor
CodeStyleManager.getInstance(getProject()).reformatText(myFile, range.getStartOffset(), range.getEndOffset());
}
});
- editor.getCaretModel().addCaretListener(new CaretListener() {
+ editor.getCaretModel().addCaretListener(new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
createFromString();
diff --git a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java
index 1a0882add180..5314b49dcf16 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java
@@ -101,7 +101,9 @@ public class CopyFilesOrDirectoriesDialog extends DialogWrapper {
PsiFile file = (PsiFile)elements[0];
String url = shortenPath(file.getVirtualFile());
text = RefactoringBundle.message(doClone ? "copy.files.clone.file.0" : "copy.files.copy.file.0", url);
- final String fileName = file.getName();
+ // keep extensions (dots) and spaces, e.g. fragment file name will be "HTML Fragment (my.sql_61).html"
+ // and leave ordinary file name AS IS
+ String fileName = PathUtil.suggestFileName(file.getName(), true, true);
myNewNameField.setText(fileName);
final int dotIdx = fileName.lastIndexOf(".");
if (dotIdx > -1) {
diff --git a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesHandler.java b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesHandler.java
index fa80f335c996..fcbc320a320f 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesHandler.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesHandler.java
@@ -18,6 +18,7 @@ package com.intellij.refactoring.copy;
import com.intellij.CommonBundle;
import com.intellij.ide.CopyPasteDelegator;
import com.intellij.ide.util.EditorHelper;
+import com.intellij.ide.util.PlatformPackageUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.project.Project;
@@ -119,11 +120,11 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase {
PsiDirectory targetDirectory;
if (element instanceof PsiDirectory) {
targetDirectory = ((PsiDirectory)element).getParentDirectory();
- assert targetDirectory != null : element;
}
else {
- targetDirectory = ((PsiFile)element).getContainingDirectory();
+ targetDirectory = PlatformPackageUtil.getDirectory(element);
}
+ assert targetDirectory != null : element;
PsiElement[] elements = {element};
CopyFilesOrDirectoriesDialog dialog = new CopyFilesOrDirectoriesDialog(elements, null, element.getProject(), true);
@@ -146,7 +147,7 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase {
directory = directory.getParentDirectory();
}
else if (element instanceof PsiFile) {
- directory = ((PsiFile)element).getContainingDirectory();
+ directory = PlatformPackageUtil.getDirectory(element);
}
else {
throw new IllegalArgumentException("unexpected element " + element);
diff --git a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java
index 76939d421741..0ff4c62461b5 100644
--- a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java
+++ b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java
@@ -127,8 +127,6 @@ public class DetailViewImpl extends JPanel implements DetailView, UserDataHolder
@Override
public void navigateInPreviewEditor(PreviewEditorState editorState) {
- myEditorState = editorState;
-
final VirtualFile file = editorState.getFile();
final LogicalPosition positionToNavigate = editorState.getNavigate();
final TextAttributes lineAttributes = editorState.getAttributes();
@@ -136,6 +134,7 @@ public class DetailViewImpl extends JPanel implements DetailView, UserDataHolder
Project project = myProject;
clearEditor();
+ myEditorState = editorState;
remove(myLabel);
if (document != null) {
if (getEditor() == null || getEditor().getDocument() != document) {
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.java
index 50e87f85baab..34b7937cb7a1 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.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,7 +27,7 @@ import org.jetbrains.annotations.Nullable;
*/
public interface AbstractIndex<Key, Value> {
@NotNull
- ValueContainer<Value> getData(Key key) throws StorageException;
+ ValueContainer<Value> getData(@NotNull Key key) throws StorageException;
- boolean processAllKeys(Processor<Key> processor, GlobalSearchScope scope, @Nullable IdFilter idFilter) throws StorageException;
+ boolean processAllKeys(@NotNull Processor<Key> processor, @NotNull GlobalSearchScope scope, @Nullable IdFilter idFilter) throws StorageException;
}
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 1648f878066c..f888981f21d4 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/ChangeTrackingValueContainer.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/ChangeTrackingValueContainer.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,6 +19,7 @@ package com.intellij.util.indexing;
import com.intellij.openapi.util.Computable;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntProcedure;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Iterator;
@@ -72,11 +73,13 @@ class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>
return getMergedData().size();
}
+ @NotNull
@Override
public Iterator<Value> getValueIterator() {
return getMergedData().getValueIterator();
}
+ @NotNull
@Override
public List<Value> toValueList() {
return getMergedData().toValueList();
@@ -87,11 +90,13 @@ class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>
return getMergedData().isAssociated(value, inputId);
}
+ @NotNull
@Override
public IntPredicate getValueAssociationPredicate(Value value) {
return getMergedData().getValueAssociationPredicate(value);
}
+ @NotNull
@Override
public IntIterator getInputIdsIterator(final Value value) {
return getMergedData().getInputIdsIterator(value);
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/CustomImplementationFileBasedIndexExtension.java b/platform/lang-impl/src/com/intellij/util/indexing/CustomImplementationFileBasedIndexExtension.java
index 32b22274dced..d504daf8e808 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/CustomImplementationFileBasedIndexExtension.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/CustomImplementationFileBasedIndexExtension.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.
@@ -23,6 +23,6 @@ import org.jetbrains.annotations.NotNull;
public abstract class CustomImplementationFileBasedIndexExtension<K, V, I> extends FileBasedIndexExtension<K, V> {
@NotNull
- public abstract UpdatableIndex<K, V, I> createIndexImplementation(final ID<K, V> indexId, @NotNull FileBasedIndex owner, @NotNull IndexStorage<K, V> storage)
+ public abstract UpdatableIndex<K, V, I> createIndexImplementation(@NotNull ID<K, V> indexId, @NotNull FileBasedIndex owner, @NotNull IndexStorage<K, V> storage)
throws StorageException;
} \ No newline at end of file
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 ed0dd1b19c6b..578529352033 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
@@ -252,8 +252,8 @@ public class FileBasedIndexImpl extends FileBasedIndex {
myConnection = connection;
}
- public static boolean isProjectOrWorkspaceFile(final VirtualFile file,
- final @Nullable FileType fileType) {
+ public static boolean isProjectOrWorkspaceFile(@NotNull VirtualFile file,
+ @Nullable FileType fileType) {
if (fileType instanceof InternalFileType) return true;
VirtualFile parent = file.isDirectory() ? file: file.getParent();
while(parent instanceof VirtualFileSystemEntry) {
@@ -369,8 +369,6 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
/**
- * @param extension
- * @param isCurrentVersionCorrupted
* @return true if registered index requires full rebuild for some reason, e.g. is just created or corrupted
*/
private <K, V> boolean registerIndexer(@NotNull final FileBasedIndexExtension<K, V> extension, final boolean isCurrentVersionCorrupted)
@@ -394,7 +392,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
return versionChanged;
}
- private <K, V> void initIndexStorage(final FileBasedIndexExtension<K, V> extension, int version, File versionFile)
+ private <K, V> void initIndexStorage(@NotNull FileBasedIndexExtension<K, V> extension, int version, @NotNull File versionFile)
throws IOException {
MapIndexStorage<K, V> storage = null;
final ID<K, V> name = extension.getName();
@@ -429,7 +427,8 @@ public class FileBasedIndexImpl extends FileBasedIndex {
ids.add(name);
}
});
- } else {
+ }
+ else {
myIndicesWithoutFileTypeInfo.add(name);
}
@@ -545,12 +544,12 @@ public class FileBasedIndexImpl extends FileBasedIndex {
@NotNull MemoryIndexStorage<K, ?> storage)
throws IOException {
final File indexStorageFile = IndexInfrastructure.getInputIndexStorageFile(indexId);
- final Ref<Boolean> isBufferingMode = new Ref<Boolean>(false);
+ final AtomicBoolean isBufferingMode = new AtomicBoolean();
final TIntObjectHashMap<Collection<K>> tempMap = new TIntObjectHashMap<Collection<K>>();
final DataExternalizer<Collection<K>> dataExternalizer = new DataExternalizer<Collection<K>>() {
@Override
- public void save(DataOutput out, @NotNull Collection<K> value) throws IOException {
+ public void save(@NotNull DataOutput out, @NotNull Collection<K> value) throws IOException {
try {
DataInputOutputUtil.writeINT(out, value.size());
for (K key : value) {
@@ -564,7 +563,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
@NotNull
@Override
- public Collection<K> read(DataInput in) throws IOException {
+ public Collection<K> read(@NotNull DataInput in) throws IOException {
try {
final int size = DataInputOutputUtil.readINT(in);
final List<K> list = new ArrayList<K>(size);
@@ -621,7 +620,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
};
- storage.addBufferingStateListsner(new MemoryIndexStorage.BufferingStateListener() {
+ storage.addBufferingStateListener(new MemoryIndexStorage.BufferingStateListener() {
@Override
public void bufferingStateChanged(boolean newState) {
synchronized (map) {
@@ -715,10 +714,11 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
@Override
- public <K> boolean processAllKeys(@NotNull final ID<K, ?> indexId, Processor<K> processor, @Nullable Project project) {
- return processAllKeys(indexId, processor, project != null ? GlobalSearchScope.allScope(project) : new EverythingGlobalScope(), null);
+ public <K> boolean processAllKeys(@NotNull final ID<K, ?> indexId, @NotNull Processor<K> processor, @Nullable Project project) {
+ return processAllKeys(indexId, processor, project == null ? new EverythingGlobalScope() : GlobalSearchScope.allScope(project), null);
}
+ @Override
public <K> boolean processAllKeys(@NotNull ID<K, ?> indexId, @NotNull Processor<K> processor, @NotNull GlobalSearchScope scope, @Nullable IdFilter idFilter) {
try {
final UpdatableIndex<K, ?, FileContent> index = getIndex(indexId);
@@ -949,7 +949,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
return null;
}
- private <K, V> boolean processValuesImpl(@NotNull final ID<K, V> indexId, final K dataKey, final boolean ensureValueProcessedOnce,
+ private <K, V> boolean processValuesImpl(@NotNull final ID<K, V> indexId, @NotNull final K dataKey, final boolean ensureValueProcessedOnce,
@Nullable final VirtualFile restrictToFile, @NotNull final ValueProcessor<V> processor,
@NotNull final GlobalSearchScope scope, @Nullable final IdFilter idFilter) {
ThrowableConvertor<UpdatableIndex<K, V, FileContent>, Boolean, StorageException> keyProcessor =
@@ -1058,6 +1058,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
});
}
+ @Override
public boolean containsFileId(int id) {
if (id < myMinId) return false;
if (id > myMaxId) return false;
@@ -1659,7 +1660,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
return (UpdatableIndex<K, V, FileContent>)pair.getFirst();
}
- private InputFilter getInputFilter(ID<?, ?> indexId) {
+ private InputFilter getInputFilter(@NotNull ID<?, ?> indexId) {
final Pair<UpdatableIndex<?, ?, FileContent>, InputFilter> pair = myIndices.get(indexId);
assert pair != null : "Index data is absent for index " + indexId;
@@ -1766,7 +1767,8 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
}
- public static FileType getFileType(VirtualFile file) {
+ @NotNull
+ public static FileType getFileType(@NotNull VirtualFile file) {
FileType fileType = file.getFileType();
if (fileType == FileTypes.PLAIN_TEXT && FileTypeManagerImpl.isFileTypeDetectedFromContent(file)) {
fileType = FileTypes.UNKNOWN;
@@ -1803,7 +1805,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
fc.putUserData(IndexingDataKeys.PROJECT, project);
}
- private void updateSingleIndex(final ID<?, ?> indexId, @NotNull final VirtualFile file, @Nullable FileContent currentFC)
+ private void updateSingleIndex(@NotNull ID<?, ?> indexId, @NotNull final VirtualFile file, @Nullable FileContent currentFC)
throws StorageException {
if (ourRebuildStatus.get(indexId).get() == REQUIRES_REBUILD) {
return; // the index is scheduled for rebuild, no need to update
@@ -1823,8 +1825,9 @@ public class FileBasedIndexImpl extends FileBasedIndex {
);
}
- private Runnable createIndexedStampUpdateRunnable(final ID<?, ?> indexId,
- final VirtualFile file,
+ @NotNull
+ private Runnable createIndexedStampUpdateRunnable(@NotNull final ID<?, ?> indexId,
+ @NotNull final VirtualFile file,
final boolean hasContent) {
return new Runnable() {
@Override
@@ -1843,7 +1846,8 @@ public class FileBasedIndexImpl extends FileBasedIndex {
};
}
- private Computable<Boolean> createUpdateComputableWithBufferingDisabled(final Computable<Boolean> update) {
+ @NotNull
+ private Computable<Boolean> createUpdateComputableWithBufferingDisabled(@NotNull final Computable<Boolean> update) {
return new Computable<Boolean>() {
@Override
public Boolean compute() {
@@ -2080,7 +2084,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
});
}
- private void invalidateIndicesForFile(final VirtualFile file, boolean markForReindex) {
+ private void invalidateIndicesForFile(@NotNull final VirtualFile file, boolean markForReindex) {
cleanProcessedFlag(file);
IndexingStamp.flushCache(file);
@@ -2439,12 +2443,12 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
}
- private boolean shouldIndexFile(final VirtualFile file, final ID<?, ?> indexId) {
+ private boolean shouldIndexFile(@NotNull VirtualFile file, @NotNull ID<?, ?> indexId) {
return getInputFilter(indexId).acceptInput(file) &&
(isMock(file) || !isFileIndexed(file, indexId));
}
- private static boolean isFileIndexed(VirtualFile file, ID<?, ?> indexId) {
+ private static boolean isFileIndexed(VirtualFile file, @NotNull ID<?, ?> indexId) {
return IndexingStamp.isFileIndexed(file, indexId, IndexInfrastructure.getIndexCreationStamp(indexId));
}
@@ -2537,7 +2541,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
@Override
- public boolean acceptInput(final VirtualFile file) {
+ public boolean acceptInput(@NotNull final VirtualFile file) {
return file instanceof VirtualFileWithId && myDelegate.acceptInput(file);
}
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexProjectHandler.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexProjectHandler.java
index 78814029780c..110db7255f84 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexProjectHandler.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexProjectHandler.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,14 +119,15 @@ public class FileBasedIndexProjectHandler extends AbstractProjectComponent imple
return myIndex.getNumberOfPendingInvalidations();
}
+ @NotNull
@Override
- public VirtualFile[] queryNeededFiles(ProgressIndicator indicator) {
+ public VirtualFile[] queryNeededFiles(@NotNull ProgressIndicator indicator) {
Collection<VirtualFile> files = myIndex.getFilesToUpdate(myProject);
return VfsUtilCore.toVirtualFileArray(files);
}
@Override
- public void processFile(FileContent fileContent) {
+ public void processFile(@NotNull FileContent fileContent) {
myIndex.processRefreshedFile(myProject, fileContent);
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.java
index 6d168332e8c5..226542e49366 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.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,23 +47,28 @@ public class IndexInfrastructure {
private IndexInfrastructure() {
}
+ @NotNull
public static File getVersionFile(@NotNull ID<?, ?> indexName) {
return new File(getIndexDirectory(indexName, true), indexName + ".ver");
}
+ @NotNull
public static File getStorageFile(@NotNull ID<?, ?> indexName) {
return new File(getIndexRootDir(indexName), indexName.toString());
}
+ @NotNull
public static File getInputIndexStorageFile(@NotNull ID<?, ?> indexName) {
- return new File(getIndexRootDir(indexName), indexName.toString()+"_inputs");
+ return new File(getIndexRootDir(indexName), indexName +"_inputs");
}
+ @NotNull
public static File getIndexRootDir(@NotNull ID<?, ?> indexName) {
return getIndexDirectory(indexName, false);
}
- private static File getIndexDirectory(ID<?, ?> indexName, boolean forVersion) {
+ @NotNull
+ private static File getIndexDirectory(@NotNull ID<?, ?> indexName, boolean forVersion) {
final String dirName = indexName.toString().toLowerCase(Locale.US);
// store StubIndices under StubUpdating index' root to ensure they are deleted
// when StubUpdatingIndex version is changed
@@ -76,7 +81,7 @@ public class IndexInfrastructure {
private static volatile long ourLastStamp; // ensure any file index stamp increases
- public static synchronized void rewriteVersion(final File file, final int version) throws IOException {
+ public static synchronized void rewriteVersion(@NotNull final File file, final int version) throws IOException {
final long prevLastModifiedValue = file.lastModified();
if (file.exists()) {
FileUtil.delete(file);
@@ -108,7 +113,7 @@ public class IndexInfrastructure {
}
}
- public static long getIndexCreationStamp(ID<?, ?> indexName) {
+ public static long getIndexCreationStamp(@NotNull ID<?, ?> indexName) {
Long version = ourIndexIdToCreationStamp.get(indexName);
if (version != null) return version.longValue();
@@ -118,7 +123,7 @@ public class IndexInfrastructure {
return stamp;
}
- public static boolean versionDiffers(final File versionFile, final int currentIndexVersion) {
+ public static boolean versionDiffers(@NotNull File versionFile, final int currentIndexVersion) {
try {
ourLastStamp = Math.max(ourLastStamp, versionFile.lastModified());
final DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(versionFile)));
@@ -137,7 +142,7 @@ public class IndexInfrastructure {
}
@Nullable
- public static VirtualFile findFileById(final PersistentFS fs, final int id) {
+ public static VirtualFile findFileById(@NotNull PersistentFS fs, final int id) {
if (ourUnitTestMode) {
final VirtualFile testFile = findTestFile(id);
if (testFile != null) {
@@ -159,7 +164,7 @@ public class IndexInfrastructure {
}
@Nullable
- public static VirtualFile findFileByIdIfCached(final PersistentFS fs, final int id) {
+ public static VirtualFile findFileByIdIfCached(@NotNull PersistentFS fs, final int id) {
if (ourUnitTestMode) {
final VirtualFile testFile = findTestFile(id);
if (testFile != null) {
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java
index 0f8bb67f00fc..1020876ca2e4 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.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,15 +33,16 @@ public interface IndexStorage<Key, Value> extends Flushable {
void addValue(Key key, int inputId, Value value) throws StorageException;
- void removeAllValues(Key key, int inputId) throws StorageException;
+ void removeAllValues(@NotNull Key key, int inputId) throws StorageException;
void clear() throws StorageException;
@NotNull
ValueContainer<Value> read(Key key) throws StorageException;
- boolean processKeys(Processor<Key> processor, GlobalSearchScope scope, @Nullable IdFilter idFilter) throws StorageException;
+ boolean processKeys(@NotNull Processor<Key> processor, GlobalSearchScope scope, @Nullable IdFilter idFilter) throws StorageException;
+ @NotNull
Collection<Key> getKeys() throws StorageException;
void close() throws StorageException;
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 ebf6906a0d1c..79a7cb684486 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.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.
@@ -26,14 +26,19 @@ import com.intellij.util.io.DataInputOutputUtil;
import gnu.trove.TObjectLongHashMap;
import gnu.trove.TObjectLongProcedure;
import gnu.trove.TObjectProcedure;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentMap;
/**
* @author Eugene Zhuravlev
@@ -100,16 +105,17 @@ public class IndexingStamp {
}
}
});
- } else {
+ }
+ else {
DataInputOutputUtil.writeTIME(stream, DataInputOutputUtil.timeBase);
}
}
- public long get(ID<?, ?> id) {
+ private long get(ID<?, ?> id) {
return myIndexStamps != null? myIndexStamps.get(id) : 0L;
}
- public void set(ID<?, ?> id, long tmst) {
+ private void set(ID<?, ?> id, long tmst) {
try {
if (tmst < 0) {
if (myIndexStamps == null) return;
@@ -130,9 +136,8 @@ public class IndexingStamp {
}
}
- private static final ConcurrentHashMap<VirtualFile, Timestamps> myTimestampsCache = new ConcurrentHashMap<VirtualFile, Timestamps>();
- private static final int CAPACITY = 100;
- private static final ArrayBlockingQueue<VirtualFile> myFinishedFiles = new ArrayBlockingQueue<VirtualFile>(CAPACITY);
+ private static final ConcurrentMap<VirtualFile, Timestamps> myTimestampsCache = new ConcurrentHashMap<VirtualFile, Timestamps>();
+ private static final BlockingQueue<VirtualFile> ourFinishedFiles = new ArrayBlockingQueue<VirtualFile>(100);
public static boolean isFileIndexed(VirtualFile file, ID<?, ?> indexName, final long indexCreationStamp) {
try {
@@ -148,7 +153,7 @@ public class IndexingStamp {
return false;
}
- public static long getIndexStamp(VirtualFile file, ID<?, ?> indexName) {
+ public static long getIndexStamp(@NotNull VirtualFile file, ID<?, ?> indexName) {
synchronized (getStripedLock(file)) {
Timestamps stamp = createOrGetTimeStamp(file);
if (stamp != null) return stamp.get(indexName);
@@ -156,7 +161,7 @@ public class IndexingStamp {
}
}
- private static Timestamps createOrGetTimeStamp(VirtualFile file) {
+ private static Timestamps createOrGetTimeStamp(@NotNull VirtualFile file) {
if (file instanceof NewVirtualFile && file.isValid()) {
Timestamps timestamps = myTimestampsCache.get(file);
if (timestamps == null) {
@@ -174,7 +179,7 @@ public class IndexingStamp {
return null;
}
- public static void update(final VirtualFile file, final ID<?, ?> indexName, final long indexCreationStamp) {
+ public static void update(@NotNull VirtualFile file, @NotNull ID<?, ?> indexName, final long indexCreationStamp) {
synchronized (getStripedLock(file)) {
try {
Timestamps stamp = createOrGetTimeStamp(file);
@@ -185,7 +190,7 @@ public class IndexingStamp {
}
}
- public static void removeAllIndexedState(VirtualFile file) {
+ public static void removeAllIndexedState(@NotNull VirtualFile file) {
synchronized (getStripedLock(file)) {
if (file instanceof NewVirtualFile && file.isValid()) {
myTimestampsCache.put(file, new Timestamps());
@@ -193,7 +198,8 @@ public class IndexingStamp {
}
}
- public static Collection<ID<?,?>> getIndexedIds(final VirtualFile file) {
+ @NotNull
+ public static Collection<ID<?,?>> getIndexedIds(@NotNull VirtualFile file) {
synchronized (getStripedLock(file)) {
try {
Timestamps stamp = createOrGetTimeStamp(file);
@@ -220,17 +226,11 @@ public class IndexingStamp {
}
public static void flushCache(@Nullable VirtualFile finishedFile) {
- if (finishedFile == null || !myFinishedFiles.offer(finishedFile)) {
- VirtualFile[] files = null;
- synchronized (myFinishedFiles) {
- int size = myFinishedFiles.size();
- if ((finishedFile == null && size > 0) || size == CAPACITY) {
- files = myFinishedFiles.toArray(new VirtualFile[size]);
- myFinishedFiles.clear();
- }
- }
+ if (finishedFile == null || !ourFinishedFiles.offer(finishedFile)) {
+ List<VirtualFile> files = new ArrayList<VirtualFile>(ourFinishedFiles.size());
+ ourFinishedFiles.drainTo(files);
- if (files != null) {
+ if (!files.isEmpty()) {
for(VirtualFile file:files) {
synchronized (getStripedLock(file)) {
Timestamps timestamp = myTimestampsCache.remove(file);
@@ -248,7 +248,7 @@ public class IndexingStamp {
}
}
}
- if (finishedFile != null) myFinishedFiles.offer(finishedFile);
+ if (finishedFile != null) ourFinishedFiles.offer(finishedFile);
}
}
@@ -257,7 +257,7 @@ public class IndexingStamp {
for(int i = 0; i < ourLocks.length; ++i) ourLocks[i] = new Object();
}
- private static Object getStripedLock(VirtualFile file) {
+ private static Object getStripedLock(@NotNull VirtualFile file) {
if (!(file instanceof NewVirtualFile)) return 0;
int id = ((NewVirtualFile)file).getId();
return ourLocks[(id & 0xFF) % ourLocks.length];
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 649bd25730fb..bbd015507e24 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.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.
@@ -60,7 +60,7 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
private final Lock l = new ReentrantLock();
private final DataExternalizer<Value> myDataExternalizer;
- private boolean myHighKeySelectivity;
+ private final boolean myHighKeySelectivity;
private final LowMemoryWatcher myLowMemoryFlusher = LowMemoryWatcher.register(new Runnable() {
@Override
public void run() {
@@ -70,7 +70,8 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
myCache.clear();
if (myMap.isDirty()) myMap.force();
}
- } finally {
+ }
+ finally {
l.unlock();
}
}
@@ -89,9 +90,7 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
@NotNull DataExternalizer<Value> valueExternalizer,
final int cacheSize,
boolean highKeySelectivity,
- boolean buildKeyHashToVirtualFileMapping
- ) throws IOException {
-
+ boolean buildKeyHashToVirtualFileMapping) throws IOException {
myStorageFile = storageFile;
myKeyDescriptor = keyDescriptor;
myCacheSize = cacheSize;
@@ -150,6 +149,7 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
myKeyHashToVirtualFileMapping = myBuildKeyHashToVirtualFileMapping ? new KeyHash2VirtualFileEnumerator(getProjectFile()) : null;
}
+ @NotNull
private File getProjectFile() {
return new File(myStorageFile.getPath() + ".project");
}
@@ -222,7 +222,7 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
}
@Override
- public boolean processKeys(final Processor<Key> processor, GlobalSearchScope scope, final IdFilter idFilter) throws StorageException {
+ public boolean processKeys(@NotNull final Processor<Key> processor, GlobalSearchScope scope, final IdFilter idFilter) throws StorageException {
l.lock();
try {
myCache.clear(); // this will ensure that all new keys are made into the map
@@ -298,7 +298,8 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
}
}
- private static TIntHashSet loadHashedIds(File fileWithCaches) throws IOException {
+ @NotNull
+ private static TIntHashSet loadHashedIds(@NotNull File fileWithCaches) throws IOException {
DataInputStream inputStream = null;
try {
inputStream = new DataInputStream(new BufferedInputStream(new FileInputStream(fileWithCaches)));
@@ -315,12 +316,13 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
if (inputStream != null) {
try {
inputStream.close();
- } catch (IOException ex) {}
+ }
+ catch (IOException ignored) {}
}
}
}
- private void saveHashedIds(TIntHashSet hashMaskSet, int largestId, GlobalSearchScope scope) {
+ private void saveHashedIds(@NotNull TIntHashSet hashMaskSet, int largestId, @NotNull GlobalSearchScope scope) {
File newFileWithCaches = getSavedProjectFileValueIds(largestId, scope);
assert newFileWithCaches != null;
DataOutputStream stream = null;
@@ -341,17 +343,22 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
}
});
if (result) myLastScannedId = largestId;
- } catch (IOException ex) {}
+ }
+ catch (IOException ignored) {
+
+ }
finally {
if (stream != null) {
try {
stream.close();
- } catch (IOException ex) {}
+ }
+ catch (IOException ignored) {}
}
}
}
- private @Nullable File getSavedProjectFileValueIds(int id, GlobalSearchScope scope) {
+ @Nullable
+ private File getSavedProjectFileValueIds(int id, @NotNull GlobalSearchScope scope) {
Project project = scope.getProject();
if (project == null) return null;
return new File(myStorageFile.getPath() + ".project."+project.hashCode() + "."+id + "." + scope.isSearchInLibraries());
@@ -423,7 +430,7 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
}
@Override
- public void removeAllValues(Key key, int inputId) throws StorageException {
+ public void removeAllValues(@NotNull Key key, int inputId) throws StorageException {
try {
myMap.markDirty();
// important: assuming the key exists in the index
@@ -436,13 +443,13 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
private static class IntPairInArrayKeyDescriptor implements KeyDescriptor<int[]>, DifferentSerializableBytesImplyNonEqualityPolicy {
@Override
- public void save(DataOutput out, int[] value) throws IOException {
+ public void save(@NotNull DataOutput out, int[] value) throws IOException {
DataInputOutputUtil.writeINT(out, value[0]);
DataInputOutputUtil.writeINT(out, value[1]);
}
@Override
- public int[] read(DataInput in) throws IOException {
+ public int[] read(@NotNull DataInput in) throws IOException {
return new int[] {DataInputOutputUtil.readINT(in), DataInputOutputUtil.readINT(in)};
}
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 f49f70db83bd..a19e2d92cddf 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.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.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Factory;
+import com.intellij.openapi.util.NotNullComputable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.search.GlobalSearchScope;
@@ -33,8 +34,10 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.Callable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -146,18 +149,20 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
}
}
+ @NotNull
@Override
public final Lock getReadLock() {
return myLock.readLock();
}
+ @NotNull
@Override
public final Lock getWriteLock() {
return myLock.writeLock();
}
@Override
- public boolean processAllKeys(Processor<Key> processor, GlobalSearchScope scope, IdFilter idFilter) throws StorageException {
+ public boolean processAllKeys(@NotNull Processor<Key> processor, @NotNull GlobalSearchScope scope, IdFilter idFilter) throws StorageException {
final Lock lock = getReadLock();
try {
lock.lock();
@@ -170,7 +175,7 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
@Override
@NotNull
- public ValueContainer<Value> getData(final Key key) throws StorageException {
+ public ValueContainer<Value> getData(@NotNull final Key key) throws StorageException {
final Lock lock = getReadLock();
try {
lock.lock();
@@ -203,6 +208,7 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
return null;
}
+ @NotNull
@Override
public final Computable<Boolean> update(final int inputId, @Nullable final Input content) {
@@ -219,17 +225,24 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
@Override
public void run() {
try {
- updateWithMap(inputId, data, new Callable<Collection<Key>>() {
+ updateWithMap(inputId, data, new NotNullComputable<Collection<Key>>() {
+ @NotNull
@Override
- public Collection<Key> call() throws Exception {
+ public Collection<Key> compute() {
if (myInputsIndex == null) {
return new SmartList<Key>((Key)(Integer)inputId);
}
- final Collection<Key> oldKeys = myInputsIndex.get(inputId);
- return oldKeys == null? Collections.<Key>emptyList() : oldKeys;
+ try {
+ Collection<Key> oldKeys = myInputsIndex.get(inputId);
+ return oldKeys == null? Collections.<Key>emptyList() : oldKeys;
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
});
- } catch (StorageException ex) {
+ }
+ catch (StorageException ex) {
exRef.set(ex);
}
}
@@ -239,20 +252,19 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
LOG.info(exRef.get());
FileBasedIndex.getInstance().requestRebuild(myIndexId);
return Boolean.FALSE;
- } else {
- return Boolean.TRUE;
}
+ return Boolean.TRUE;
}
};
}
protected void updateWithMap(final int inputId,
@NotNull Map<Key, Value> newData,
- @NotNull Callable<Collection<Key>> oldKeysGetter) throws StorageException {
+ @NotNull NotNullComputable<Collection<Key>> oldKeysGetter) throws StorageException {
getWriteLock().lock();
try {
try {
- for (Key key : oldKeysGetter.call()) {
+ for (Key key : oldKeysGetter.compute()) {
myStorage.removeAllValues(key, inputId);
}
}
@@ -277,7 +289,8 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
}
});
if (!b) throw exceptionRef.get();
- } else {
+ }
+ else {
for (Map.Entry<Key, Value> entry : newData.entrySet()) {
myStorage.addValue(entry.getKey(), inputId, entry.getValue());
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java
index 3ef7d2ac4e98..2ae474b73858 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.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,6 +34,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
*/
public class MemoryIndexStorage<Key, Value> implements IndexStorage<Key, Value> {
private final Map<Key, ChangeTrackingValueContainer<Value>> myMap = new HashMap<Key, ChangeTrackingValueContainer<Value>>();
+ @NotNull
private final IndexStorage<Key, Value> myBackendStorage;
private final List<BufferingStateListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private final AtomicBoolean myBufferingEnabled = new AtomicBoolean(false);
@@ -44,19 +45,20 @@ public class MemoryIndexStorage<Key, Value> implements IndexStorage<Key, Value>
void memoryStorageCleared();
}
- public MemoryIndexStorage(IndexStorage<Key, Value> backend) {
+ public MemoryIndexStorage(@NotNull IndexStorage<Key, Value> backend) {
myBackendStorage = backend;
}
+ @NotNull
public IndexStorage<Key, Value> getBackendStorage() {
return myBackendStorage;
}
- public void addBufferingStateListsner(BufferingStateListener listener) {
+ public void addBufferingStateListener(@NotNull BufferingStateListener listener) {
myListeners.add(listener);
}
- public void removeBufferingStateListsner(BufferingStateListener listener) {
+ public void removeBufferingStateListener(@NotNull BufferingStateListener listener) {
myListeners.remove(listener);
}
@@ -99,6 +101,7 @@ public class MemoryIndexStorage<Key, Value> implements IndexStorage<Key, Value>
myBackendStorage.flush();
}
+ @NotNull
@Override
public Collection<Key> getKeys() throws StorageException {
final Set<Key> keys = new HashSet<Key>();
@@ -107,7 +110,7 @@ public class MemoryIndexStorage<Key, Value> implements IndexStorage<Key, Value>
}
@Override
- public boolean processKeys(final Processor<Key> processor, GlobalSearchScope scope, IdFilter idFilter) throws StorageException {
+ public boolean processKeys(@NotNull final Processor<Key> processor, GlobalSearchScope scope, IdFilter idFilter) throws StorageException {
final Set<Key> stopList = new HashSet<Key>();
Processor<Key> decoratingProcessor = new Processor<Key>() {
@@ -129,7 +132,7 @@ public class MemoryIndexStorage<Key, Value> implements IndexStorage<Key, Value>
}
stopList.add(key);
}
- return myBackendStorage.processKeys(stopList.size() == 0 && myMap.size() == 0 ? processor : decoratingProcessor, scope, idFilter);
+ return myBackendStorage.processKeys(stopList.isEmpty() && myMap.isEmpty() ? processor : decoratingProcessor, scope, idFilter);
}
@Override
@@ -147,7 +150,7 @@ public class MemoryIndexStorage<Key, Value> implements IndexStorage<Key, Value>
}
@Override
- public void removeAllValues(Key key, int inputId) throws StorageException {
+ public void removeAllValues(@NotNull Key key, int inputId) throws StorageException {
if (myBufferingEnabled.get()) {
getMemValueContainer(key).removeAssociatedValue(inputId);
return;
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 2a18906d80f8..a4975f100d96 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.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.
@@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CollectingContentIterator;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -49,8 +50,9 @@ public class UnindexedFilesUpdater implements CacheUpdater {
return myIndex.getNumberOfPendingInvalidations();
}
+ @NotNull
@Override
- public VirtualFile[] queryNeededFiles(ProgressIndicator indicator) {
+ public VirtualFile[] queryNeededFiles(@NotNull ProgressIndicator indicator) {
myIndex.filesUpdateStarted(myProject);
CollectingContentIterator finder = myIndex.createContentIterator(indicator);
long l = System.currentTimeMillis();
@@ -66,10 +68,11 @@ public class UnindexedFilesUpdater implements CacheUpdater {
}
@Override
- public void processFile(final FileContent fileContent) {
+ public void processFile(@NotNull FileContent fileContent) {
try {
myIndex.indexFileContent(myProject, fileContent);
- } finally {
+ }
+ finally {
IndexingStamp.flushCache(fileContent.getVirtualFile());
}
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.java
index 589db0f47e58..4b431eddb5d7 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.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.indexing;
import com.intellij.openapi.util.Computable;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.locks.Lock;
@@ -31,12 +32,13 @@ public interface UpdatableIndex<Key, Value, Input> extends AbstractIndex<Key,Val
void flush() throws StorageException;
- /**
- */
+ @NotNull
Computable<Boolean> update(int inputId, @Nullable Input content);
-
+
+ @NotNull
Lock getReadLock();
-
+
+ @NotNull
Lock getWriteLock();
void dispose();
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 d901751fadf4..47efe30fbf84 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainer.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainer.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,6 +16,8 @@
package com.intellij.util.indexing;
+import org.jetbrains.annotations.NotNull;
+
import java.util.Iterator;
import java.util.List;
@@ -35,15 +37,19 @@ public abstract class ValueContainer<Value> {
abstract static class IntPredicate {
abstract boolean contains(int id);
}
-
+
+ @NotNull
public abstract IntIterator getInputIdsIterator(Value value);
public abstract boolean isAssociated(Value value, int inputId);
+ @NotNull
public abstract IntPredicate getValueAssociationPredicate(Value value);
+ @NotNull
public abstract Iterator<Value> getValueIterator();
+ @NotNull
public abstract List<Value> toValueList();
public abstract int size();
@@ -53,7 +59,7 @@ public abstract class ValueContainer<Value> {
boolean perform(int id, T value);
}
- public final boolean forEach(final ContainerAction<Value> action) {
+ public final boolean forEach(@NotNull ContainerAction<Value> action) {
for (final Iterator<Value> valueIterator = getValueIterator(); valueIterator.hasNext();) {
final Value value = valueIterator.next();
for (final IntIterator intIterator = getInputIdsIterator(value); intIterator.hasNext();) {
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 ae9424d7733e..ddc538154177 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.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.diagnostic.Logger;
import com.intellij.util.SmartList;
import com.intellij.util.containers.EmptyIterator;
import gnu.trove.*;
+import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -139,6 +140,7 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
return true;
}
+ @NotNull
@Override
public Iterator<Value> getValueIterator() {
if (myInputIdMapping != null) {
@@ -190,6 +192,7 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
}
}
+ @NotNull
@Override
public List<Value> toValueList() {
if (myInputIdMapping == null) {
@@ -216,6 +219,7 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
return false;
}
+ @NotNull
@Override
public IntPredicate getValueAssociationPredicate(Value value) {
final Object input = getInput(value);
@@ -247,6 +251,7 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
};
}
+ @NotNull
@Override
public IntIterator getInputIdsIterator(Value value) {
final Object input = getInput(value);
@@ -335,6 +340,7 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
}
};
+ @NotNull
public ValueContainerImpl<Value> copy() {
ValueContainerImpl<Value> container = new ValueContainerImpl<Value>();
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 c4385b491733..3bf0ece67a99 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.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.util.indexing;
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
@@ -71,7 +86,7 @@ class ValueContainerMap<Key, Value> extends PersistentHashMap<Key, ValueContaine
}
@Override
- public void save(final DataOutput out, @NotNull final ValueContainer<T> container) throws IOException {
+ public void save(@NotNull final DataOutput out, @NotNull final ValueContainer<T> container) throws IOException {
saveImpl(out, container);
}
@@ -79,29 +94,24 @@ class ValueContainerMap<Key, Value> extends PersistentHashMap<Key, ValueContaine
DataInputOutputUtil.writeSINT(out, -inputId);
}
- private void saveImpl(final DataOutput out, @NotNull final ValueContainer<T> container) throws IOException {
+ private void saveImpl(@NotNull DataOutput out, @NotNull final ValueContainer<T> container) throws IOException {
DataInputOutputUtil.writeSINT(out, container.size());
for (final Iterator<T> valueIterator = container.getValueIterator(); valueIterator.hasNext();) {
final T value = valueIterator.next();
myExternalizer.save(out, value);
final ValueContainer.IntIterator ids = container.getInputIdsIterator(value);
- if (ids != null) {
- DataInputOutputUtil.writeSINT(out, ids.size());
- while (ids.hasNext()) {
- final int id = ids.next();
- DataInputOutputUtil.writeSINT(out, id);
- }
- }
- else {
- DataInputOutputUtil.writeSINT(out, 0);
+ DataInputOutputUtil.writeSINT(out, ids.size());
+ while (ids.hasNext()) {
+ final int id = ids.next();
+ DataInputOutputUtil.writeSINT(out, id);
}
}
}
@NotNull
@Override
- public ValueContainerImpl<T> read(final DataInput in) throws IOException {
+ public ValueContainerImpl<T> read(@NotNull final DataInput in) throws IOException {
DataInputStream stream = (DataInputStream)in;
final ValueContainerImpl<T> valueContainer = new ValueContainerImpl<T>();
diff --git a/platform/lang-impl/src/com/intellij/webcore/packaging/InstalledPackagesPanel.java b/platform/lang-impl/src/com/intellij/webcore/packaging/InstalledPackagesPanel.java
index f394c836475d..6dd7aebfe2d5 100644
--- a/platform/lang-impl/src/com/intellij/webcore/packaging/InstalledPackagesPanel.java
+++ b/platform/lang-impl/src/com/intellij/webcore/packaging/InstalledPackagesPanel.java
@@ -2,6 +2,7 @@ package com.intellij.webcore.packaging;
import com.google.common.collect.Lists;
import com.intellij.icons.AllIcons;
+import com.intellij.ide.ActivityTracker;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
@@ -397,6 +398,9 @@ public class InstalledPackagesPanel extends JPanel {
myPackagesTable.setPaintBusy(false);
myPackagesTable.getEmptyText().setText(StatusText.DEFAULT_EMPTY_TEXT);
updateUninstallUpgrade();
+ // Action button presentations won't be updated if no events occur (e.g. mouse isn't moving, keys aren't being pressed).
+ // In that case emulating activity will help:
+ ActivityTracker.getInstance().inc();
}
public void doUpdatePackages(@NotNull final PackageManagementService packageManagementService) {
diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java b/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java
index 3c307500d6ce..24a7603e45f7 100644
--- a/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java
+++ b/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java
@@ -30,7 +30,10 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.Clock;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.encoding.EncodingRegistry;
diff --git a/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java b/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java
index a42a1bfab18a..445ac0126047 100644
--- a/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java
+++ b/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java
@@ -240,7 +240,7 @@ public class GeneralCommandLine implements UserDataHolder {
commands = CommandLineUtil.toCommandLine(myExePath, myProgramParams.getList());
}
catch (ExecutionException e) {
- LOG.warn(e);
+ LOG.info(e);
throw e;
}
@@ -248,7 +248,7 @@ public class GeneralCommandLine implements UserDataHolder {
return startProcess(commands);
}
catch (IOException e) {
- LOG.warn(e);
+ LOG.info(e);
throw new ProcessNotCreatedException(e.getMessage(), e, this);
}
}
diff --git a/platform/platform-api/src/com/intellij/ide/caches/CacheUpdater.java b/platform/platform-api/src/com/intellij/ide/caches/CacheUpdater.java
index 219f23bced4f..359924225981 100644
--- a/platform/platform-api/src/com/intellij/ide/caches/CacheUpdater.java
+++ b/platform/platform-api/src/com/intellij/ide/caches/CacheUpdater.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.ide.caches;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
public interface CacheUpdater {
int getNumberOfPendingUpdateJobs();
- VirtualFile[] queryNeededFiles(ProgressIndicator indicator);
+ @NotNull
+ VirtualFile[] queryNeededFiles(@NotNull ProgressIndicator indicator);
- void processFile(FileContent fileContent);
+ void processFile(@NotNull FileContent fileContent);
void updatingDone();
diff --git a/platform/platform-api/src/com/intellij/lang/LanguageDialect.java b/platform/platform-api/src/com/intellij/lang/LanguageDialect.java
index 532d4d89da17..f5bc6b2bceea 100644
--- a/platform/platform-api/src/com/intellij/lang/LanguageDialect.java
+++ b/platform/platform-api/src/com/intellij/lang/LanguageDialect.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,6 +18,8 @@ package com.intellij.lang;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+/** @deprecated use {@linkplain Language#Language(Language, String, String...)} (to remove in IDEA 15) */
+@SuppressWarnings("UnusedDeclaration")
public abstract class LanguageDialect extends Language {
public LanguageDialect(@NonNls @NotNull String id, @NotNull Language baseLanguage) {
super(baseLanguage, id, "");
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java
index 4ae67c9da5d7..9e53c35f7cac 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java
@@ -15,11 +15,11 @@
*/
package com.intellij.openapi.actionSystem;
+import com.intellij.openapi.actionSystem.ex.ActionUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.ArrayList;
/**
* This class purpose is to reserve action-id in a plugin.xml so the action appears in Keymap.
@@ -74,13 +74,8 @@ public final class EmptyAction extends AnAction {
}
public static void registerActionShortcuts(JComponent component, final JComponent fromComponent) {
- @SuppressWarnings("unchecked")
- final ArrayList<AnAction> actionList =
- (ArrayList<AnAction>)fromComponent.getClientProperty(ourClientProperty);
- if (actionList != null) {
- for (AnAction anAction : actionList) {
- anAction.registerCustomShortcutSet(anAction.getShortcutSet(), component);
- }
+ for (AnAction anAction : ActionUtil.getActions(fromComponent)) {
+ anAction.registerCustomShortcutSet(anAction.getShortcutSet(), component);
}
}
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java
index b515b84e8f3f..2004b55c66d4 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java
@@ -115,7 +115,8 @@ public interface IdeActions {
@NonNls String ACTION_FIND_NEXT = "FindNext";
@NonNls String ACTION_FIND_PREVIOUS = "FindPrevious";
@NonNls String ACTION_SELECT_NEXT_OCCURENCE = "SelectNextOccurrence";
- @NonNls String ACTION_UNSELECT_LAST_OCCURENCE = "UnselectLastOccurrence";
+ @NonNls String ACTION_SELECT_ALL_OCCURRENCES = "SelectAllOccurrences";
+ @NonNls String ACTION_UNSELECT_PREVIOUS_OCCURENCE = "UnselectPreviousOccurrence";
@NonNls String ACTION_COMPILE = "Compile";
@NonNls String ACTION_COMPILE_PROJECT = "CompileProject";
@NonNls String ACTION_MAKE_MODULE = "MakeModule";
@@ -189,6 +190,8 @@ public interface IdeActions {
@NonNls String GROUP_OTHER_MENU = "OtherMenu";
@NonNls String GROUP_EDITOR = "EditorActions";
@NonNls String GROUP_DEBUGGER = "DebuggerActions";
+
+ @NonNls String ACTION_TOGGLE_LINE_BREAKPOINT = "ToggleLineBreakpoint";
@NonNls String ACTION_REFRESH = "Refresh";
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java
index 8132f9e65990..e0dc548fd452 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java
@@ -27,7 +27,9 @@ import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import javax.swing.*;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
public class ActionUtil {
@@ -166,5 +168,10 @@ public class ActionUtil {
}
}
-
+ @NotNull
+ public static List<AnAction> getActions(@NotNull JComponent component) {
+ Object property = component.getClientProperty(AnAction.ourClientProperty);
+ //noinspection unchecked
+ return property == null ? Collections.<AnAction>emptyList() : (List<AnAction>)property;
+ }
}
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/SimpleContent.java b/platform/platform-api/src/com/intellij/openapi/diff/SimpleContent.java
index 55960fb8296e..9a0af4ad83a2 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/SimpleContent.java
+++ b/platform/platform-api/src/com/intellij/openapi/diff/SimpleContent.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.diff;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
@@ -29,8 +30,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.*;
-import java.nio.charset.Charset;
import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
/**
* Allows to compare some text not associated with file or document.
@@ -210,16 +211,18 @@ public class SimpleContent extends DiffContent {
private static class LineSeparators {
private String mySeparator;
- public String correctText(String text) {
- LineTokenizer lineTokenizer = new LineTokenizer(text);
- String[] lines = lineTokenizer.execute();
+ @NotNull
+ public String correctText(@NotNull String text) {
+ DiffString.LineTokenizer lineTokenizer = new DiffString.LineTokenizer(DiffString.create(text));
+ DiffString[] lines = lineTokenizer.execute();
mySeparator = lineTokenizer.getLineSeparator();
LOG.assertTrue(mySeparator == null || !mySeparator.isEmpty());
if (mySeparator == null) mySeparator = SystemProperties.getLineSeparator();
- return LineTokenizer.concatLines(lines);
+ return DiffString.concatenate(lines).toString();
}
- public String restoreText(String text) {
+ @NotNull
+ public String restoreText(@NotNull String text) {
if (mySeparator == null) throw new NullPointerException();
return text.replaceAll("\n", mySeparator);
}
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 cf674d6abe72..8058f6c754a9 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.LineTokenizer;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.util.Producer;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.datatransfer.DataFlavor;
@@ -45,12 +46,27 @@ public class EditorModificationUtil {
int selectionStart = selectionModel.getSelectionStart();
int selectionEnd = selectionModel.getSelectionEnd();
- editor.getCaretModel().moveToOffset(selectionStart);
+ VisualPosition selectionStartPosition = selectionModel.getSelectionStartPosition();
+ if (editor.isColumnMode() && editor.getCaretModel().supportsMultipleCarets() && selectionStartPosition != null) {
+ editor.getCaretModel().moveToVisualPosition(selectionStartPosition);
+ }
+ else {
+ editor.getCaretModel().moveToOffset(selectionStart);
+ }
selectionModel.removeSelection();
editor.getDocument().deleteString(selectionStart, selectionEnd);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
+ public static void deleteSelectedTextForAllCarets(@NotNull final Editor editor) {
+ editor.getCaretModel().runForEachCaret(new CaretAction() {
+ @Override
+ public void perform(Caret caret) {
+ deleteSelectedText(editor);
+ }
+ });
+ }
+
public static void deleteBlockSelection(Editor editor) {
SelectionModel selectionModel = editor.getSelectionModel();
if (!selectionModel.hasBlockSelection()) return;
@@ -81,14 +97,24 @@ public class EditorModificationUtil {
editor.getSelectionModel().setBlockSelection(new LogicalPosition(startLine, caretColumn), new LogicalPosition(endLine, caretColumn));
}
- public static void insertStringAtCaret(Editor editor, String s) {
+ public static void insertStringAtCaret(Editor editor, @NotNull String s) {
insertStringAtCaret(editor, s, false, true);
}
- public static int insertStringAtCaret(Editor editor, String s, boolean toProcessOverwriteMode, boolean toMoveCaret) {
+ 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, boolean toMoveCaret, int caretShift) {
final SelectionModel selectionModel = editor.getSelectionModel();
if (selectionModel.hasSelection()) {
- editor.getCaretModel().moveToOffset(selectionModel.getSelectionStart(), true);
+ VisualPosition startPosition = selectionModel.getSelectionStartPosition();
+ if (editor.isColumnMode() && editor.getCaretModel().supportsMultipleCarets() && startPosition != null) {
+ editor.getCaretModel().moveToVisualPosition(startPosition);
+ }
+ else {
+ editor.getCaretModel().moveToOffset(selectionModel.getSelectionStart(), true);
+ }
}
// There is a possible case that particular soft wraps become hard wraps if the caret is located at soft wrap-introduced virtual
@@ -120,7 +146,7 @@ public class EditorModificationUtil {
document.replaceString(oldOffset, Math.min(endOffset, oldOffset + s.length()), s);
}
- int offset = oldOffset + s.length();
+ int offset = oldOffset + filler.length() + caretShift;
if (toMoveCaret){
editor.getCaretModel().moveToOffset(offset, true);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
@@ -139,7 +165,7 @@ public class EditorModificationUtil {
if (text == null) return null;
if (editor.getCaretModel().supportsMultipleCarets()) {
- int caretCount = editor.getCaretModel().getAllCarets().size();
+ int caretCount = editor.getCaretModel().getCaretCount();
final Iterator<String> segments = new ClipboardTextPerCaretSplitter().split(text, caretCount).iterator();
editor.getCaretModel().runForEachCaret(new CaretAction() {
@Override
@@ -365,6 +391,62 @@ public class EditorModificationUtil {
}
}
+ public static void typeInStringAtCaretHonorMultipleCarets(final Editor editor, @NotNull final String str, final boolean toProcessOverwriteMode) {
+ typeInStringAtCaretHonorMultipleCarets(editor, str, toProcessOverwriteMode, str.length());
+ }
+
+ /**
+ * Inserts given string at each caret's position. Effective caret shift will be equal to <code>caretShift</code> for each caret.
+ */
+ public static void typeInStringAtCaretHonorMultipleCarets(final Editor editor, @NotNull final String str, final boolean toProcessOverwriteMode, final int caretShift)
+ throws ReadOnlyFragmentModificationException
+ {
+ Document doc = editor.getDocument();
+ final SelectionModel selectionModel = editor.getSelectionModel();
+ if (selectionModel.hasBlockSelection()) {
+ RangeMarker guard = selectionModel.getBlockSelectionGuard();
+ if (guard != null) {
+ DocumentEvent evt = new MockDocumentEvent(doc, editor.getCaretModel().getOffset());
+ ReadOnlyFragmentModificationException e = new ReadOnlyFragmentModificationException(evt, guard);
+ EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(doc).handle(e);
+ }
+ else {
+ final LogicalPosition start = selectionModel.getBlockStart();
+ final LogicalPosition end = selectionModel.getBlockEnd();
+ assert start != null;
+ assert end != null;
+
+ int column = Math.min(start.column, end.column);
+ int startLine = Math.min(start.line, end.line);
+ int endLine = Math.max(start.line, end.line);
+ deleteBlockSelection(editor);
+ for (int i = startLine; i <= endLine; i++) {
+ editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(i, column));
+ insertStringAtCaret(editor, str, toProcessOverwriteMode, true, caretShift);
+ }
+ selectionModel.setBlockSelection(new LogicalPosition(startLine, column + str.length()),
+ new LogicalPosition(endLine, column + str.length()));
+ }
+ }
+ else {
+ editor.getCaretModel().runForEachCaret(new CaretAction() {
+ @Override
+ public void perform(Caret caret) {
+ insertStringAtCaret(editor, str, toProcessOverwriteMode, true, caretShift);
+ }
+ });
+ }
+ }
+
+ public static void moveAllCaretsRelatively(@NotNull Editor editor, final int caretShift) {
+ editor.getCaretModel().runForEachCaret(new CaretAction() {
+ @Override
+ public void perform(Caret caret) {
+ caret.moveToOffset(caret.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 0c468aa373eb..f296c643d5bb 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
@@ -17,7 +17,7 @@ package com.intellij.openapi.editor;
import com.intellij.codeStyle.CodeStyleFacade;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.components.AbstractProjectComponent;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -36,11 +36,13 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
-public class LazyRangeMarkerFactory extends AbstractProjectComponent {
+public class LazyRangeMarkerFactory {
+ private final Project myProject;
private final ConcurrentMap<VirtualFile,WeakList<LazyMarker>> myMarkers = new ConcurrentWeakHashMap<VirtualFile, WeakList<LazyMarker>>();
public LazyRangeMarkerFactory(@NotNull Project project, @NotNull final FileDocumentManager fileDocumentManager) {
- super(project);
+ myProject = project;
+
EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new DocumentAdapter() {
@Override
public void beforeDocumentChange(DocumentEvent e) {
@@ -71,7 +73,7 @@ public class LazyRangeMarkerFactory extends AbstractProjectComponent {
}
public static LazyRangeMarkerFactory getInstance(Project project) {
- return project.getComponent(LazyRangeMarkerFactory.class);
+ return ServiceManager.getService(project, LazyRangeMarkerFactory.class);
}
@NotNull
@@ -92,8 +94,7 @@ public class LazyRangeMarkerFactory extends AbstractProjectComponent {
return ApplicationManager.getApplication().runReadAction(new Computable<RangeMarker>() {
@Override
public RangeMarker compute() {
- FileDocumentManager fdm = FileDocumentManager.getInstance();
- final Document document = fdm.getCachedDocument(file);
+ final Document document = FileDocumentManager.getInstance().getCachedDocument(file);
if (document != null) {
final int offset = calculateOffset(myProject, file, document, line, column);
return document.createRangeMarker(offset, offset, persistent);
@@ -122,7 +123,7 @@ public class LazyRangeMarkerFactory extends AbstractProjectComponent {
}
@Nullable
- private RangeMarker getOrCreateDelegate() {
+ protected final RangeMarker getOrCreateDelegate() {
if (myDelegate == null) {
Document document = FileDocumentManager.getInstance().getDocument(myFile);
if (document == null) {
@@ -218,6 +219,18 @@ public class LazyRangeMarkerFactory extends AbstractProjectComponent {
return document.createRangeMarker(offset, offset);
}
+
+ @Override
+ public int getStartOffset() {
+ getOrCreateDelegate();
+ return super.getStartOffset();
+ }
+
+ @Override
+ public int getEndOffset() {
+ getOrCreateDelegate();
+ return super.getEndOffset();
+ }
}
private static int calculateOffset(@NotNull Project project, @NotNull VirtualFile file, @NotNull Document document, final int line, final int column) {
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 28bc0f0510ed..1e49937e7765 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
@@ -64,18 +64,7 @@ public class TypedAction {
try {
final String str = String.valueOf(charTyped);
CommandProcessor.getInstance().setCurrentCommandName(EditorBundle.message("typing.in.editor.command.name"));
-
- if (editor.getCaretModel().getAllCarets().size() == 1) { // temporary fix for completion - going forward we shouldn't use this check
- EditorModificationUtil.typeInStringAtCaretHonorBlockSelection(editor, str, true);
- }
- else {
- editor.getCaretModel().runForEachCaret(new CaretAction() {
- @Override
- public void perform(Caret caret) {
- EditorModificationUtil.typeInStringAtCaretHonorBlockSelection(editor, str, true);
- }
- });
- }
+ EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, str, true);
}
catch (ReadOnlyFragmentModificationException e) {
EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(doc).handle(e);
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 9561581bc38b..c9e3a0f2145a 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
@@ -55,31 +55,38 @@ public class OpenFileDescriptor implements Navigatable {
private boolean myUseCurrentWindow = false;
public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int offset) {
- this(project, file, -1, -1, offset, false);
+ this(project, file, -1, -1, offset, null, false);
}
public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int logicalLine, int logicalColumn) {
- this(project, file, logicalLine, logicalColumn, -1, false);
+ this(project, file, logicalLine, logicalColumn, -1, null, false);
}
public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file,
int logicalLine, int logicalColumn, boolean persistent) {
- this(project, file, logicalLine, logicalColumn, -1, persistent);
+ this(project, file, logicalLine, logicalColumn, -1, null, persistent);
}
public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file) {
- this(project, file, -1, -1, -1, false);
+ this(project, file, -1, -1, -1, null, false);
+ }
+
+ public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, @NotNull RangeMarker rangeMarker) {
+ this(project, file, -1, -1, -1, rangeMarker, false);
}
private OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file,
- int logicalLine, int logicalColumn, int offset, boolean persistent) {
+ int logicalLine, int logicalColumn, int offset, @Nullable RangeMarker rangeMarker, boolean persistent) {
myProject = project;
myFile = file;
myLogicalLine = logicalLine;
myLogicalColumn = logicalColumn;
myOffset = offset;
- if (offset >= 0) {
+ if (rangeMarker != null) {
+ myRangeMarker = rangeMarker;
+ }
+ else if (offset >= 0) {
myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, offset);
}
else if (logicalLine >= 0 ){
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 b4502de5090c..30788880ff66 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/Messages.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/Messages.java
@@ -219,7 +219,7 @@ public class Messages {
/**
* @return number of button pressed: from 0 up to options.length-1 inclusive, or -1 for Cancel
*/
- public static int showDialog(Component parent, String message, @NotNull String title, @NotNull String[] options, int defaultOptionIndex, @Nullable Icon icon) {
+ public static int showDialog(@NotNull Component parent, String message, @NotNull String title, @NotNull String[] options, int defaultOptionIndex, @Nullable Icon icon) {
if (isApplicationInUnitTestOrHeadless()) {
return ourTestImplementation.show(message);
}
@@ -309,7 +309,7 @@ public class Messages {
showDialog(project, message, title, new String[]{OK_BUTTON}, 0, icon);
}
- public static void showMessageDialog(Component parent, String message, @NotNull String title, @Nullable Icon icon) {
+ public static void showMessageDialog(@NotNull Component parent, String message, @NotNull String title, @Nullable Icon icon) {
try {
if (canShowMacSheetPanel()) {
MacMessages.getInstance().showOkMessageDialog(title, message, OK_BUTTON, SwingUtilities.getWindowAncestor(parent));
@@ -386,7 +386,7 @@ public class Messages {
* @return {@link #YES} if user pressed "Yes" or {@link #NO} if user pressed "No" button.
*/
@YesNoResult
- public static int showYesNoDialog(Component parent, String message, @NotNull String title, @Nullable Icon icon) {
+ public static int showYesNoDialog(@NotNull Component parent, String message, @NotNull String title, @Nullable Icon icon) {
try {
if (canShowMacSheetPanel()) {
return MacMessages.getInstance().showYesNoDialog(title, message, YES_BUTTON, NO_BUTTON, SwingUtilities.getWindowAncestor(parent));
@@ -508,7 +508,7 @@ public class Messages {
* @return {@link #OK} if user pressed "Ok" or {@link #CANCEL} if user pressed "Cancel" button.
*/
@OkCancelResult
- public static int showOkCancelDialog(Component parent, String message, @NotNull String title, @NotNull String okText, @NotNull String cancelText, Icon icon) {
+ public static int showOkCancelDialog(@NotNull Component parent, String message, @NotNull String title, @NotNull String okText, @NotNull String cancelText, Icon icon) {
try {
if (canShowMacSheetPanel()) {
int result =
@@ -526,7 +526,7 @@ public class Messages {
* @return {@link #OK} if user pressed "Ok" or {@link #CANCEL} if user pressed "Cancel" button.
*/
@OkCancelResult
- public static int showOkCancelDialog(Component parent, String message, String title, Icon icon) {
+ public static int showOkCancelDialog(@NotNull Component parent, String message, String title, Icon icon) {
return showOkCancelDialog(parent, message, title, OK_BUTTON, CANCEL_BUTTON, icon);
}
@@ -619,7 +619,7 @@ public class Messages {
showDialog(project, message, title, new String[]{OK_BUTTON}, 0, getErrorIcon());
}
- public static void showErrorDialog(Component component, String message, @Nls @NotNull String title) {
+ public static void showErrorDialog(@NotNull Component component, String message, @Nls @NotNull String title) {
try {
if (canShowMacSheetPanel()) {
MacMessages.getInstance().showErrorDialog(title, message, OK_BUTTON, SwingUtilities.getWindowAncestor(component));
@@ -632,7 +632,7 @@ public class Messages {
showDialog(component, message, title, new String[]{OK_BUTTON}, 0, getErrorIcon());
}
- public static void showErrorDialog(Component component, String message) {
+ public static void showErrorDialog(@NotNull Component component, String message) {
try {
if (canShowMacSheetPanel()) {
MacMessages.getInstance().showErrorDialog(CommonBundle.getErrorTitle(), message, OK_BUTTON, SwingUtilities.getWindowAncestor(
@@ -678,7 +678,7 @@ public class Messages {
showDialog(project, message, title, new String[]{OK_BUTTON}, 0, getWarningIcon());
}
- public static void showWarningDialog(Component component, String message, @NotNull String title) {
+ public static void showWarningDialog(@NotNull Component component, String message, @NotNull String title) {
try {
if (canShowMacSheetPanel()) {
MacMessages.getInstance().showErrorDialog(title, message, OK_BUTTON, SwingUtilities.getWindowAncestor(component));
@@ -751,7 +751,7 @@ public class Messages {
* @return {@link #YES} if user pressed "Yes" or {@link #NO} if user pressed "No", or {@link #CANCEL} if user pressed "Cancel" button.
*/
@YesNoCancelResult
- public static int showYesNoCancelDialog(Component parent,
+ public static int showYesNoCancelDialog(@NotNull Component parent,
String message,
@NotNull String title,
@NotNull String yes,
@@ -775,7 +775,7 @@ public class Messages {
* @return {@link #YES} if user pressed "Yes" or {@link #NO} if user pressed "No", or {@link #CANCEL} if user pressed "Cancel" button.
*/
@YesNoCancelResult
- public static int showYesNoCancelDialog(Component parent, String message, String title, Icon icon) {
+ public static int showYesNoCancelDialog(@NotNull Component parent, String message, String title, Icon icon) {
return showYesNoCancelDialog(parent, message, title, YES_BUTTON, NO_BUTTON, CANCEL_BUTTON, icon);
}
@@ -878,7 +878,7 @@ public class Messages {
* @return trimmed input string or <code>null</code> if user cancelled dialog.
*/
@Nullable
- public static String showInputDialog(Component parent, String message, String title, @Nullable Icon icon) {
+ public static String showInputDialog(@NotNull Component parent, String message, String title, @Nullable Icon icon) {
return showInputDialog(parent, message, title, icon, null, null);
}
@@ -942,7 +942,7 @@ public class Messages {
}
@Nullable
- public static String showInputDialog(Component parent,
+ public static String showInputDialog(@NotNull Component parent,
String message,
String title,
@Nullable Icon icon,
@@ -1051,7 +1051,7 @@ public class Messages {
/** @deprecated It looks awful! */
@Deprecated
- public static int showChooseDialog(Component parent, String message, String title, String[] values, String initialValue, Icon icon) {
+ public static int showChooseDialog(@NotNull Component parent, String message, String title, String[] values, String initialValue, Icon icon) {
if (isApplicationInUnitTestOrHeadless()) {
return ourTestImplementation.show(message);
}
@@ -1250,15 +1250,15 @@ public class Messages {
_init(title, message, options, defaultOptionIndex, focusedOptionIndex, icon, null);
}
- public MessageDialog(Component parent, String message, String title, @NotNull String[] options, int defaultOptionIndex, @Nullable Icon icon) {
+ public MessageDialog(@NotNull Component parent, String message, String title, @NotNull String[] options, int defaultOptionIndex, @Nullable Icon icon) {
this(parent, message, title, options, defaultOptionIndex, icon, false);
}
- public MessageDialog(Component parent, String message, String title, @NotNull String[] options, int defaultOptionIndex, @Nullable Icon icon, boolean canBeParent) {
+ public MessageDialog(@NotNull Component parent, String message, String title, @NotNull String[] options, int defaultOptionIndex, @Nullable Icon icon, boolean canBeParent) {
this(parent, message, title, options, defaultOptionIndex, -1, icon, canBeParent);
}
- public MessageDialog(Component parent,
+ public MessageDialog(@NotNull Component parent,
String message,
String title,
@NotNull String[] options,
@@ -1644,7 +1644,7 @@ public class Messages {
this(project, message, title, icon, initialValue, validator, new String[]{OK_BUTTON, CANCEL_BUTTON}, 0);
}
- public InputDialog(Component parent,
+ public InputDialog(@NotNull Component parent,
String message,
String title,
@Nullable Icon icon,
@@ -1881,7 +1881,7 @@ public class Messages {
this(project, message, title, icon, values, initialValue, new String[]{OK_BUTTON, CANCEL_BUTTON}, 0);
}
- public ChooseDialog(Component parent, String message, String title, @Nullable Icon icon, String[] values, String initialValue) {
+ public ChooseDialog(@NotNull Component parent, String message, String title, @Nullable Icon icon, String[] values, String initialValue) {
super(parent, message, title, new String[]{OK_BUTTON, CANCEL_BUTTON}, 0, icon);
myComboBox.setModel(new DefaultComboBoxModel(values));
myComboBox.setSelectedItem(initialValue);
diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/impl/StubVirtualFile.java b/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/impl/StubVirtualFile.java
index 48765456e681..7d391758cfdb 100644
--- a/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/impl/StubVirtualFile.java
+++ b/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/impl/StubVirtualFile.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.
@@ -30,69 +30,85 @@ import java.io.InputStream;
import java.io.OutputStream;
public class StubVirtualFile extends VirtualFile {
+ @Override
@NotNull
public byte[] contentsToByteArray() throws IOException {
throw new UnsupportedOperationException("contentsToByteArray is not implemented");
}
+ @Override
public VirtualFile[] getChildren() {
throw new UnsupportedOperationException("getChildren is not implemented");
}
+ @Override
@NotNull
public VirtualFileSystem getFileSystem() {
throw new UnsupportedOperationException("getFileSystem is not implemented");
}
+ @Override
public InputStream getInputStream() throws IOException {
throw new UnsupportedOperationException("getInputStream is not implemented");
}
+ @Override
public long getLength() {
throw new UnsupportedOperationException("getLength is not implemented");
}
+ @Override
@NotNull
@NonNls
public String getName() {
throw new UnsupportedOperationException("getName is not implemented");
}
+ @Override
@NotNull
public OutputStream getOutputStream(final Object requestor, final long newModificationStamp, final long newTimeStamp) throws IOException {
throw new UnsupportedOperationException("getOutputStream is not implemented");
}
+ @Override
@Nullable
public VirtualFile getParent() {
throw new UnsupportedOperationException("getParent is not implemented");
}
+ @Override
+ @NotNull
public String getPath() {
throw new UnsupportedOperationException("getPath is not implemented");
}
+ @Override
public long getTimeStamp() {
throw new UnsupportedOperationException("getTimeStamp is not implemented");
}
+ @Override
@NotNull
public String getUrl() {
throw new UnsupportedOperationException("getUrl is not implemented");
}
+ @Override
public boolean isDirectory() {
throw new UnsupportedOperationException("isDirectory is not implemented");
}
+ @Override
public boolean isValid() {
throw new UnsupportedOperationException("isValid is not implemented");
}
+ @Override
public boolean isWritable() {
throw new UnsupportedOperationException("isWritable is not implemented");
}
+ @Override
public void refresh(final boolean asynchronous, final boolean recursive, final Runnable postRunnable) {
throw new UnsupportedOperationException("refresh is not implemented");
}
diff --git a/platform/platform-api/src/com/intellij/openapi/wm/IdeGlassPaneUtil.java b/platform/platform-api/src/com/intellij/openapi/wm/IdeGlassPaneUtil.java
index 0c76911b6821..67375287e7b2 100644
--- a/platform/platform-api/src/com/intellij/openapi/wm/IdeGlassPaneUtil.java
+++ b/platform/platform-api/src/com/intellij/openapi/wm/IdeGlassPaneUtil.java
@@ -16,11 +16,12 @@
package com.intellij.openapi.wm;
-import com.intellij.openapi.ui.Painter;
import com.intellij.openapi.Disposable;
+import com.intellij.openapi.ui.Painter;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Disposer;
-import com.intellij.util.ui.update.UiNotifyConnector;
import com.intellij.util.ui.update.Activatable;
+import com.intellij.util.ui.update.UiNotifyConnector;
import javax.swing.*;
import java.awt.*;
@@ -69,6 +70,9 @@ public class IdeGlassPaneUtil {
public static boolean canBePreprocessed(MouseEvent e) {
Component c = SwingUtilities.getDeepestComponentAt(e.getComponent(), e.getX(), e.getY());
+ if (JBPopupFactory.getInstance().getParentBalloonFor(c) != null) {
+ return false;
+ }
if (c instanceof IdeGlassPane.TopComponent) {
return ((IdeGlassPane.TopComponent)c).canBePreprocessed(e);
diff --git a/platform/platform-api/src/com/intellij/util/Alarm.java b/platform/platform-api/src/com/intellij/util/Alarm.java
index 269b81b630c3..60d32332e4de 100644
--- a/platform/platform-api/src/com/intellij/util/Alarm.java
+++ b/platform/platform-api/src/com/intellij/util/Alarm.java
@@ -69,6 +69,10 @@ public class Alarm implements Disposable {
}
}
+ public void checkDisposed() {
+ LOG.assertTrue(!myDisposed, "Already disposed");
+ }
+
public enum ThreadToUse {
SWING_THREAD,
SHARED_THREAD,
@@ -158,7 +162,7 @@ public class Alarm implements Disposable {
protected void _addRequest(@NotNull Runnable request, long delayMillis, ModalityState modalityState) {
synchronized (LOCK) {
- LOG.assertTrue(!myDisposed, "Already disposed");
+ checkDisposed();
final Request requestToSchedule = new Request(request, modalityState, delayMillis);
if (myActivationComponent == null || myActivationComponent.isShowing()) {
diff --git a/platform/platform-api/src/com/intellij/util/ui/Animator.java b/platform/platform-api/src/com/intellij/util/ui/Animator.java
index a7d9301a791f..9b0256012fd3 100644
--- a/platform/platform-api/src/com/intellij/util/ui/Animator.java
+++ b/platform/platform-api/src/com/intellij/util/ui/Animator.java
@@ -131,7 +131,10 @@ public abstract class Animator implements Disposable {
public void resume() {
final Application app = ApplicationManager.getApplication();
- if (app == null || app.isUnitTestMode()) return;
+ if (app == null || app.isUnitTestMode()) {
+ animationDone();
+ return;
+ }
if (myCycleDuration == 0) {
myCurrentFrame = myTotalFrames - 1;
diff --git a/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java b/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java
index 97ecd972b350..d9a1ba7a4e29 100644
--- a/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java
+++ b/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java
@@ -787,9 +787,9 @@ public final class TreeUtil {
if (rowCount == oldRowCount) break;
oldRowCount = rowCount;
for (int i = 0; i < rowCount; i++) {
- tree.expandRow(i);
+ tree.expandRow(i);
+ }
}
- }
while (true);
}
diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java
index caecb4c31d7d..c4c8c8f7d8c7 100644
--- a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java
@@ -104,7 +104,7 @@ public class HintManagerImpl extends HintManager implements Disposable {
myAnActionListener = new MyAnActionListener();
actionManagerEx.addAnActionListener(myAnActionListener);
- myCaretMoveListener = new CaretListener() {
+ myCaretMoveListener = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
hideHints(HIDE_BY_ANY_KEY, false, false);
@@ -131,6 +131,7 @@ public class HintManagerImpl extends HintManager implements Disposable {
myEditorFocusListener = new FocusAdapter() {
@Override
public void focusLost(final FocusEvent e) {
+ if (UIUtil.isFocusProxy(e.getOppositeComponent())) return;
myHideAlarm.addRequest(new Runnable() {
@Override
public void run() {
diff --git a/platform/platform-impl/src/com/intellij/designer/model/Property.java b/platform/platform-impl/src/com/intellij/designer/model/Property.java
index b44b5991edf1..9f902c8f864e 100644
--- a/platform/platform-impl/src/com/intellij/designer/model/Property.java
+++ b/platform/platform-impl/src/com/intellij/designer/model/Property.java
@@ -120,6 +120,10 @@ public abstract class Property<T extends PropertiesContainer> {
return false;
}
+ public boolean closeEditorDuringRefresh() {
+ return false;
+ }
+
//////////////////////////////////////////////////////////////////////////////////////////
//
// Presentation
diff --git a/platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java b/platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java
index 9ea80470d7f1..e8deef934e8e 100644
--- a/platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java
+++ b/platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java
@@ -848,7 +848,7 @@ public abstract class PropertyTable extends JBTable {
if (isSetValue) {
if (property.needRefreshPropertyList() || needRefresh[0]) {
- update(myContainers, null, false);
+ update(myContainers, null, property.closeEditorDuringRefresh());
}
else {
myModel.fireTableRowsUpdated(row, row);
@@ -1113,7 +1113,7 @@ public abstract class PropertyTable extends JBTable {
}
if (setValueAtRow(editingRow, value)) {
- if (!continueEditing) {
+ if (!continueEditing && editingRow != -1) {
PropertyEditor editor = myProperties.get(editingRow).getEditor();
editor.removePropertyEditorListener(myPropertyEditorListener);
removeEditor();
diff --git a/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java b/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java
index cf959586f60b..9933dd59f46a 100644
--- a/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java
+++ b/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java
@@ -227,6 +227,9 @@ public final class ScriptRunnerUtil {
long millisTimeout,
@Nullable String commandLine) {
if (processHandler.isProcessTerminated()) {
+ if (commandLine == null && processHandler instanceof BaseOSProcessHandler) {
+ commandLine = ((BaseOSProcessHandler) processHandler).getCommandLine();
+ }
LOG.warn("Process '" + commandLine + "' is already terminated!");
return;
}
diff --git a/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java b/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java
index 6e6c052d0e3b..39886a2eb20a 100644
--- a/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java
+++ b/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.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,6 +33,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.ui.HyperlinkAdapter;
import com.intellij.ui.awt.RelativePoint;
+import com.intellij.util.SystemProperties;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.PropertyKey;
@@ -119,6 +120,10 @@ public class SystemHealthMonitor extends ApplicationComponent.Adapter {
}
private static void startDiskSpaceMonitoring() {
+ if (SystemProperties.getBooleanProperty("idea.no.system.path.space.monitoring", false)) {
+ return;
+ }
+
final File file = new File(PathManager.getSystemPath());
final AtomicBoolean reported = new AtomicBoolean();
final ThreadLocal<Future<Long>> ourFreeSpaceCalculation = new ThreadLocal<Future<Long>>();
diff --git a/platform/platform-impl/src/com/intellij/ide/dnd/FileCopyPasteUtil.java b/platform/platform-impl/src/com/intellij/ide/dnd/FileCopyPasteUtil.java
index cecde708b61b..dca050bcd31f 100644
--- a/platform/platform-impl/src/com/intellij/ide/dnd/FileCopyPasteUtil.java
+++ b/platform/platform-impl/src/com/intellij/ide/dnd/FileCopyPasteUtil.java
@@ -51,8 +51,8 @@ public class FileCopyPasteUtil {
public static DataFlavor createDataFlavor(@NotNull final String mimeType, @Nullable final Class<?> klass, final boolean register) {
try {
- final String typeString = klass != null ? mimeType + ";class=" + klass.getName() : mimeType;
- final DataFlavor flavor = new DataFlavor(typeString);
+ final DataFlavor flavor =
+ klass != null ? new DataFlavor(mimeType + ";class=" + klass.getName(), null, klass.getClassLoader()) : new DataFlavor(mimeType);
if (register) {
final FlavorMap map = SystemFlavorMap.getDefaultFlavorMap();
diff --git a/platform/platform-impl/src/com/intellij/ide/impl/SelectInEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/impl/SelectInEditorManagerImpl.java
index 6c7efde06915..2eebf984707a 100644
--- a/platform/platform-impl/src/com/intellij/ide/impl/SelectInEditorManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/impl/SelectInEditorManagerImpl.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,14 @@ public class SelectInEditorManagerImpl extends SelectInEditorManager implements
releaseAll();
}
+ @Override
+ public void caretAdded(CaretEvent e) {
+ }
+
+ @Override
+ public void caretRemoved(CaretEvent e) {
+ }
+
private void releaseAll() {
if (mySegmentHighlighter != null && myEditor != null){
mySegmentHighlighter.dispose();
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginHeaderPanel.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginHeaderPanel.java
index e6664c0845e6..285efb41f1a2 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginHeaderPanel.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginHeaderPanel.java
@@ -83,6 +83,7 @@ public class PluginHeaderPanel {
//data
myName.setText("<html><body>" + plugin.getName() + "</body></html>");
myCategory.setText(plugin.getCategory() == null ? "UNKNOWN" : plugin.getCategory().toUpperCase());
+ final boolean hasNewerVersion = InstalledPluginsTableModel.hasNewerVersion(plugin.getPluginId());
if (plugin instanceof PluginNode) {
final PluginNode node = (PluginNode)plugin;
@@ -93,7 +94,7 @@ public class PluginHeaderPanel {
myUpdated.setText("Updated " + DateFormatUtil.formatDate(node.getDate()));
switch (node.getStatus()) {
case PluginNode.STATUS_INSTALLED:
- myActionId = InstalledPluginsTableModel.hasNewerVersion(plugin.getPluginId()) ? ACTION_ID.UPDATE : ACTION_ID.UNINSTALL;
+ myActionId = hasNewerVersion ? ACTION_ID.UPDATE : ACTION_ID.UNINSTALL;
break;
case PluginNode.STATUS_DOWNLOADED:
myActionId = ACTION_ID.RESTART;
@@ -114,10 +115,10 @@ public class PluginHeaderPanel {
final String version = plugin.getVersion();
myVersion.setText("Version: " + (version == null ? "N/A" : version));
myUpdated.setVisible(false);
- if (!plugin.isBundled()) {
+ if (!plugin.isBundled() || hasNewerVersion) {
if (((IdeaPluginDescriptorImpl)plugin).isDeleted()) {
myActionId = ACTION_ID.RESTART;
- } else if (InstalledPluginsTableModel.hasNewerVersion(plugin.getPluginId())) {
+ } else if (hasNewerVersion) {
myActionId = ACTION_ID.UPDATE;
} else {
myActionId = ACTION_ID.UNINSTALL;
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 174ca5a3f372..3b2ac0553fba 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java
@@ -17,6 +17,7 @@ package com.intellij.ide.plugins;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.extensions.PluginId;
+import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.ui.Gray;
@@ -93,6 +94,11 @@ public class PluginsTableRenderer extends DefaultTableCellRenderer {
}
if (myPluginDescriptor.isBundled()) {
myCategory.setText(myCategory.getText() + "[Bundled]");
+ myStatus.setIcon(AllIcons.Nodes.PluginJB);
+ }
+ final String vendor = myPluginDescriptor.getVendor();
+ if (vendor != null && vendor.toLowerCase().contains("jetbrains")) {
+ myStatus.setIcon(AllIcons.Nodes.PluginJB);
}
myPanel.setBackground(bg);
@@ -120,6 +126,7 @@ public class PluginsTableRenderer extends DefaultTableCellRenderer {
if (!isSelected) myName.setForeground(FileStatus.ADDED.getColor());
//todo[kb] set proper icon
//myStatus.setText("[Downloaded]");
+ myStatus.setIcon(AllIcons.Nodes.PluginRestart);
//myPanel.setToolTipText(IdeBundle.message("plugin.download.status.tooltip"));
//myStatus.setBorder(BorderFactory.createEmptyBorder(0, LEFT_MARGIN, 0, 0));
}
@@ -136,6 +143,16 @@ public class PluginsTableRenderer extends DefaultTableCellRenderer {
//todo[kb] set proper icon
//myStatus.setText("v." + pluginNode.getInstalledVersion() + (hasNewerVersion ? (" -> " + pluginNode.getVersion()) : ""));
}
+
+ if (InstalledPluginsTableModel.hasNewerVersion(myPluginDescriptor.getPluginId())) {
+ myStatus.setIcon(AllIcons.Nodes.Pluginobsolete);
+ if (!isSelected) {
+ myName.setForeground(JBColor.RED);
+ }
+ }
+ if (!myPluginDescriptor.isEnabled()) {
+ myStatus.setIcon(IconLoader.getDisabledIcon(myStatus.getIcon()));
+ }
}
return myPanel;
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java
index f858002f0743..818466ba3153 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java
@@ -273,6 +273,10 @@ public class DarculaLaf extends BasicLookAndFeel {
}
protected Object parseValue(String key, @NotNull String value) {
+ if ("null".equals(value)) {
+ return null;
+ }
+
if (key.endsWith("Insets")) {
final List<String> numbers = StringUtil.split(value, ",");
return new InsetsUIResource(Integer.parseInt(numbers.get(0)),
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties
index b975ff8a666d..1f29a08d8612 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties
@@ -122,6 +122,9 @@ Button.darcula.selection.color2=233143
Button.darcula.selectedButtonForeground=bbbbbb
Button.darcula.disabledText.shadow=00000000
+ToggleButton.border=com.intellij.ide.ui.laf.darcula.ui.DarculaButtonPainter
+ToggleButtonUI=com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI
+
MenuItem.acceleratorForeground=eeeeee
PopupMenu.translucentBackground=3c3f41
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 f4fbc75dd935..8deb957d21f1 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
@@ -50,7 +50,7 @@ public class DarculaButtonUI extends BasicButtonUI {
final Insets ins = border.getBorderInsets(c);
final int yOff = (ins.top + ins.bottom) / 4;
if (!square) {
- if (((JButton)c).isDefaultButton()) {
+ if (c instanceof JButton && ((JButton)c).isDefaultButton()) {
((Graphics2D)g).setPaint(UIUtil.getGradientPaint(0, 0, getSelectedButtonColor1(), 0, c.getHeight(), getSelectedButtonColor2()));
}
else {
@@ -100,7 +100,7 @@ public class DarculaButtonUI extends BasicButtonUI {
@Override
public void update(Graphics g, JComponent c) {
super.update(g, c);
- if (((JButton)c).isDefaultButton() && !SystemInfo.isMac) {
+ if (c instanceof JButton && ((JButton)c).isDefaultButton() && !SystemInfo.isMac) {
if (!c.getFont().isBold()) {
c.setFont(c.getFont().deriveFont(Font.BOLD));
}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaToggleButtonUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaToggleButtonUI.java
new file mode 100644
index 000000000000..b35ac61ca8c1
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaToggleButtonUI.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.ui.laf.darcula.ui;
+
+import javax.swing.*;
+import javax.swing.plaf.ComponentUI;
+
+public class DarculaToggleButtonUI extends DarculaButtonUI {
+ @SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
+ public static ComponentUI createUI(JComponent c) {
+ return new DarculaToggleButtonUI();
+ }
+}
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 116adfe47398..cd99cb129fd0 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
@@ -130,6 +130,9 @@ Button.darcula.selection.color2=3a6bc6
Button.darcula.selectedButtonForeground=f0f0f0
Button.darcula.disabledText.shadow=ffffff
+ToggleButton.border=com.intellij.ide.ui.laf.darcula.ui.DarculaButtonPainter
+ToggleButtonUI=com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI
+
MenuItem.acceleratorForeground=505050
PopupMenu.translucentBackground=e8e8e8
diff --git a/platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java b/platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java
index 14e6d9265f07..855c898ae207 100644
--- a/platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java
+++ b/platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.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.
@@ -27,6 +27,7 @@ import com.intellij.openapi.project.DumbServiceImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.TimeoutUtil;
+import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
@@ -50,14 +51,15 @@ public class ToggleDumbModeAction extends AnAction implements DumbAware {
return 0;
}
- public VirtualFile[] queryNeededFiles(ProgressIndicator indicator) {
+ @NotNull
+ public VirtualFile[] queryNeededFiles(@NotNull ProgressIndicator indicator) {
while (myDumb) {
TimeoutUtil.sleep(100);
}
return VirtualFile.EMPTY_ARRAY;
}
- public void processFile(FileContent fileContent) {
+ public void processFile(@NotNull FileContent fileContent) {
}
public void updatingDone() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/actions/DiffPanelComboBoxAction.java b/platform/platform-impl/src/com/intellij/openapi/diff/actions/DiffPanelComboBoxAction.java
new file mode 100644
index 000000000000..b3ef9595782f
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/actions/DiffPanelComboBoxAction.java
@@ -0,0 +1,94 @@
+package com.intellij.openapi.diff.actions;
+
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
+import com.intellij.openapi.diff.DiffBundle;
+import com.intellij.openapi.diff.ex.DiffPanelEx;
+import com.intellij.openapi.diff.impl.DiffPanelImpl;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Map;
+
+public abstract class DiffPanelComboBoxAction<T> extends ComboBoxAction implements DumbAware {
+ @NotNull private final Map<T, AnAction> myActions = new HashMap<T, AnAction>();
+ @NotNull private final T[] myActionOrder;
+
+ protected DiffPanelComboBoxAction(@NotNull T[] actionOrder) {
+ myActionOrder = actionOrder;
+ }
+
+ @NotNull
+ protected abstract String getActionName();
+
+ @NotNull
+ protected abstract T getCurrentOption(@NotNull DiffPanelEx diffPanel);
+
+ @Nullable
+ private static DiffPanelEx getDiffPanel(@NotNull DataContext context) {
+ return DiffPanelImpl.fromDataContext(context);
+ }
+
+ protected void addAction(T key, @NotNull AnAction action) {
+ myActions.put(key, action);
+ }
+
+ @Override
+ public JComponent createCustomComponent(final Presentation presentation) {
+ JPanel panel = new JPanel(new BorderLayout());
+ final JLabel label = new JLabel(getActionName());
+ label.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
+ panel.add(label, BorderLayout.WEST);
+ panel.add(super.createCustomComponent(presentation), BorderLayout.CENTER);
+ return panel;
+ }
+
+ @NotNull
+ @Override
+ protected DefaultActionGroup createPopupActionGroup(JComponent button) {
+ DefaultActionGroup actionGroup = new DefaultActionGroup();
+ for (T option : myActionOrder) {
+ actionGroup.add(myActions.get(option));
+ }
+ return actionGroup;
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ Presentation presentation = e.getPresentation();
+ DiffPanelEx diffPanel = getDiffPanel(e.getDataContext());
+ if (diffPanel != null && diffPanel.getComponent().isDisplayable()) {
+ AnAction action = myActions.get(getCurrentOption(diffPanel));
+ Presentation templatePresentation = action.getTemplatePresentation();
+ presentation.setIcon(templatePresentation.getIcon());
+ presentation.setText(templatePresentation.getText());
+ presentation.setEnabled(true);
+ }
+ else {
+ presentation.setIcon(null);
+ presentation.setText(DiffBundle.message("diff.panel.combo.box.action.not.available.action.name"));
+ presentation.setEnabled(false);
+ }
+ }
+
+ protected static abstract class DiffPanelAction extends DumbAwareAction {
+ public DiffPanelAction(@NotNull String text) {
+ super(text);
+ }
+
+ public void actionPerformed(AnActionEvent e) {
+ final DiffPanelEx diffPanel = getDiffPanel(e.getDataContext());
+ if (diffPanel != null) {
+ perform(diffPanel);
+ }
+ }
+
+ protected abstract void perform(@NotNull DiffPanelEx diffPanel);
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/actions/HighlightModeAction.java b/platform/platform-impl/src/com/intellij/openapi/diff/actions/HighlightModeAction.java
index 8ae6fa277738..65f5eb346120 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/actions/HighlightModeAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/actions/HighlightModeAction.java
@@ -15,89 +15,48 @@
*/
package com.intellij.openapi.diff.actions;
-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 com.intellij.openapi.diff.DiffBundle;
import com.intellij.openapi.diff.ex.DiffPanelEx;
-import com.intellij.openapi.diff.impl.DiffPanelImpl;
import com.intellij.openapi.diff.impl.processing.HighlightMode;
-import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.project.DumbAwareAction;
-import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-import java.awt.*;
-import java.util.Map;
-
-public class HighlightModeAction extends ComboBoxAction implements DumbAware {
- private final Map<HighlightMode, AnAction> myActions = new HashMap<HighlightMode, AnAction>();
- private static final HighlightMode[] ourActionOrder =
- new HighlightMode[]{HighlightMode.BY_WORD, HighlightMode.BY_LINE, HighlightMode.NO_HIGHLIGHTING};
+public class HighlightModeAction extends DiffPanelComboBoxAction<HighlightMode> {
+ private static final HighlightMode[] ourActionOrder = new HighlightMode[]{
+ HighlightMode.BY_WORD,
+ HighlightMode.BY_LINE,
+ HighlightMode.NO_HIGHLIGHTING
+ };
public HighlightModeAction() {
- myActions.put(HighlightMode.BY_WORD,
- new SetHighlightModeAction(DiffBundle.message("diff.acton.highlight.mode.action.by.word"), HighlightMode.BY_WORD));
- myActions.put(HighlightMode.BY_LINE,
- new SetHighlightModeAction(DiffBundle.message("diff.acton.highlight.mode.action.by.line"), HighlightMode.BY_LINE));
- myActions.put(HighlightMode.NO_HIGHLIGHTING,
- new SetHighlightModeAction(DiffBundle.message("diff.acton.highlight.mode.action.no.highlighting"),
- HighlightMode.NO_HIGHLIGHTING));
+ super(ourActionOrder);
+ addAction(HighlightMode.BY_WORD, new HighlightingModeAction(DiffBundle.message("diff.acton.highlight.mode.action.by.word"), HighlightMode.BY_WORD));
+ addAction(HighlightMode.BY_LINE, new HighlightingModeAction(DiffBundle.message("diff.acton.highlight.mode.action.by.line"), HighlightMode.BY_LINE));
+ addAction(HighlightMode.NO_HIGHLIGHTING, new HighlightingModeAction(DiffBundle.message("diff.acton.highlight.mode.action.no.highlighting"), HighlightMode.NO_HIGHLIGHTING));
}
+ @NotNull
@Override
- public JComponent createCustomComponent(final Presentation presentation) {
- JPanel panel = new JPanel(new BorderLayout());
- final JLabel label = new JLabel(DiffBundle.message("diff.acton.highlight.mode.action.name"));
- label.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
- panel.add(label, BorderLayout.WEST);
- panel.add(super.createCustomComponent(presentation), BorderLayout.CENTER);
- return panel;
+ protected String getActionName() {
+ return DiffBundle.message("diff.acton.highlight.mode.action.name");
}
@NotNull
- protected DefaultActionGroup createPopupActionGroup(JComponent button) {
- DefaultActionGroup actionGroup = new DefaultActionGroup();
- for (HighlightMode comparisonPolicy : ourActionOrder) {
- actionGroup.add(myActions.get(comparisonPolicy));
- }
- return actionGroup;
- }
-
- public void update(AnActionEvent e) {
- super.update(e);
- Presentation presentation = e.getPresentation();
- DiffPanelEx diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext());
- if (diffPanel != null && diffPanel.getComponent().isDisplayable()) {
- AnAction action = myActions.get(diffPanel.getHighlightMode());
- Presentation templatePresentation = action.getTemplatePresentation();
- presentation.setIcon(templatePresentation.getIcon());
- presentation.setText(templatePresentation.getText());
- presentation.setEnabled(true);
- }
- else {
- presentation.setIcon(null);
- presentation.setText(DiffBundle.message("diff.acton.highlight.mode.not.available.action.name"));
- presentation.setEnabled(false);
- }
+ @Override
+ protected HighlightMode getCurrentOption(@NotNull DiffPanelEx diffPanel) {
+ return diffPanel.getHighlightMode();
}
- private static class SetHighlightModeAction extends DumbAwareAction {
+ private static class HighlightingModeAction extends DiffPanelAction {
private final HighlightMode myHighlightMode;
- public SetHighlightModeAction(String text, HighlightMode mode) {
+ public HighlightingModeAction(String text, HighlightMode highlightMode) {
super(text);
- myHighlightMode = mode;
+ myHighlightMode = highlightMode;
}
- public void actionPerformed(AnActionEvent e) {
- final DiffPanelImpl diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext());
- if (diffPanel != null) {
- diffPanel.setHighlightMode(myHighlightMode);
- }
+ @Override
+ protected void perform(@NotNull DiffPanelEx diffPanel) {
+ diffPanel.setHighlightMode(myHighlightMode);
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java b/platform/platform-impl/src/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java
index 930db0e4f337..a46d8b1516c7 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java
@@ -15,74 +15,38 @@
*/
package com.intellij.openapi.diff.actions;
-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 com.intellij.openapi.diff.DiffBundle;
import com.intellij.openapi.diff.ex.DiffPanelEx;
import com.intellij.openapi.diff.impl.ComparisonPolicy;
-import com.intellij.openapi.diff.impl.DiffPanelImpl;
-import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.project.DumbAwareAction;
-import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-import java.awt.*;
-import java.util.Map;
-
-public class IgnoreWhiteSpacesAction extends ComboBoxAction implements DumbAware {
- private final Map<ComparisonPolicy, AnAction> myActions = new HashMap<ComparisonPolicy, AnAction>();
+public class IgnoreWhiteSpacesAction extends DiffPanelComboBoxAction<ComparisonPolicy> {
private static final ComparisonPolicy[] ourActionOrder = new ComparisonPolicy[]{
ComparisonPolicy.DEFAULT,
ComparisonPolicy.TRIM_SPACE,
- ComparisonPolicy.IGNORE_SPACE};
+ ComparisonPolicy.IGNORE_SPACE
+ };
public IgnoreWhiteSpacesAction() {
- myActions.put(ComparisonPolicy.DEFAULT, new IgnoringPolicyAction(DiffBundle.message("diff.acton.ignore.whitespace.policy.do.not.ignore"), ComparisonPolicy.DEFAULT));
- myActions.put(ComparisonPolicy.TRIM_SPACE, new IgnoringPolicyAction(DiffBundle.message("diff.acton.ignore.whitespace.policy.leading.and.trailing"), ComparisonPolicy.TRIM_SPACE));
- myActions.put(ComparisonPolicy.IGNORE_SPACE, new IgnoringPolicyAction(DiffBundle.message("diff.acton.ignore.whitespace.policy.all"), ComparisonPolicy.IGNORE_SPACE));
+ super(ourActionOrder);
+ addAction(ComparisonPolicy.DEFAULT, new IgnoringPolicyAction(DiffBundle.message("diff.acton.ignore.whitespace.policy.do.not.ignore"), ComparisonPolicy.DEFAULT));
+ addAction(ComparisonPolicy.TRIM_SPACE, new IgnoringPolicyAction(DiffBundle.message("diff.acton.ignore.whitespace.policy.leading.and.trailing"), ComparisonPolicy.TRIM_SPACE));
+ addAction(ComparisonPolicy.IGNORE_SPACE, new IgnoringPolicyAction(DiffBundle.message("diff.acton.ignore.whitespace.policy.all"), ComparisonPolicy.IGNORE_SPACE));
}
+ @NotNull
@Override
- public JComponent createCustomComponent(final Presentation presentation) {
- JPanel panel = new JPanel(new BorderLayout());
- final JLabel label = new JLabel(DiffBundle.message("ignore.whitespace.acton.name"));
- label.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
- panel.add(label, BorderLayout.WEST);
- panel.add(super.createCustomComponent(presentation), BorderLayout.CENTER);
- return panel;
+ protected String getActionName() {
+ return DiffBundle.message("ignore.whitespace.acton.name");
}
@NotNull
- protected DefaultActionGroup createPopupActionGroup(JComponent button) {
- DefaultActionGroup actionGroup = new DefaultActionGroup();
- for (ComparisonPolicy comparisonPolicy : ourActionOrder) {
- actionGroup.add(myActions.get(comparisonPolicy));
- }
- return actionGroup;
- }
-
- public void update(AnActionEvent e) {
- super.update(e);
- Presentation presentation = e.getPresentation();
- DiffPanelEx diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext());
- if (diffPanel != null && diffPanel.getComponent().isDisplayable()) {
- AnAction action = myActions.get(diffPanel.getComparisonPolicy());
- Presentation templatePresentation = action.getTemplatePresentation();
- presentation.setIcon(templatePresentation.getIcon());
- presentation.setText(templatePresentation.getText());
- presentation.setEnabled(true);
- } else {
- presentation.setIcon(null);
- presentation.setText(DiffBundle.message("ignore.whitespace.action.not.available.action.name"));
- presentation.setEnabled(false);
- }
+ @Override
+ protected ComparisonPolicy getCurrentOption(@NotNull DiffPanelEx diffPanel) {
+ return diffPanel.getComparisonPolicy();
}
- private static class IgnoringPolicyAction extends DumbAwareAction {
+ private static class IgnoringPolicyAction extends DiffPanelAction {
private final ComparisonPolicy myPolicy;
public IgnoringPolicyAction(String text, ComparisonPolicy policy) {
@@ -90,11 +54,9 @@ public class IgnoreWhiteSpacesAction extends ComboBoxAction implements DumbAware
myPolicy = policy;
}
- public void actionPerformed(AnActionEvent e) {
- final DiffPanelImpl diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext());
- if (diffPanel != null) {
- diffPanel.setComparisonPolicy(myPolicy);
- }
+ @Override
+ protected void perform(@NotNull DiffPanelEx diffPanel) {
+ diffPanel.setComparisonPolicy(myPolicy);
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/CurrentLineMarker.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/CurrentLineMarker.java
index 8d7559dc575d..515fc9df9936 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/CurrentLineMarker.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/CurrentLineMarker.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.
@@ -64,4 +64,14 @@ public class CurrentLineMarker implements CaretListener {
if (isHiden()) return;
set();
}
+
+ @Override
+ public void caretAdded(CaretEvent e) {
+
+ }
+
+ @Override
+ public void caretRemoved(CaretEvent e) {
+
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java
index a3715fdeaec4..1ee83be74224 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java
@@ -19,11 +19,10 @@ import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.DiffContentUtil;
import com.intellij.openapi.diff.DiffViewer;
-import com.intellij.openapi.diff.LineTokenizer;
-import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.external.DiffManagerImpl;
import com.intellij.openapi.diff.impl.fragments.Fragment;
import com.intellij.openapi.diff.impl.fragments.LineFragment;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.impl.util.FocusDiffSide;
import com.intellij.openapi.diff.impl.util.TextDiffType;
import com.intellij.openapi.editor.Document;
@@ -34,7 +33,6 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.FrameWrapper;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ImageLoader;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -47,7 +45,7 @@ public class DiffUtil {
private DiffUtil() {
}
- public static void initDiffFrame(Project project, FrameWrapper frameWrapper, final DiffViewer diffPanel, final JComponent mainComponent) {
+ public static void initDiffFrame(Project project, @NotNull FrameWrapper frameWrapper, @NotNull final DiffViewer diffPanel, final JComponent mainComponent) {
frameWrapper.setComponent(mainComponent);
frameWrapper.setProject(project);
frameWrapper.setImage(ImageLoader.loadFromResource("/diff/Diff.png"));
@@ -56,15 +54,17 @@ public class DiffUtil {
}
@Nullable
- public static FocusDiffSide getFocusDiffSide(DataContext dataContext) {
+ public static FocusDiffSide getFocusDiffSide(@NotNull DataContext dataContext) {
return FocusDiffSide.DATA_KEY.getData(dataContext);
}
- public static String[] convertToLines(@NotNull String text) {
- return new LineTokenizer(text).execute();
+ @NotNull
+ public static DiffString[] convertToLines(@NotNull String text) {
+ return DiffString.create(text).tokenize();
}
- public static FileType[] chooseContentTypes(DiffContent[] contents) {
+ @NotNull
+ public static FileType[] chooseContentTypes(@NotNull DiffContent[] contents) {
FileType commonType = FileTypes.PLAIN_TEXT;
for (DiffContent content : contents) {
FileType contentType = content.getContentType();
@@ -78,7 +78,7 @@ public class DiffUtil {
return result;
}
- public static boolean isWritable(DiffContent content) {
+ public static boolean isWritable(@NotNull DiffContent content) {
Document document = content.getDocument();
return document != null && document.isWritable();
}
@@ -92,7 +92,7 @@ public class DiffUtil {
return editor;
}
- public static void drawBoldDottedFramingLines(Graphics2D g, int startX, int endX, int startY, int bottomY, Color color) {
+ public static void drawBoldDottedFramingLines(@NotNull Graphics2D g, int startX, int endX, int startY, int bottomY, @NotNull Color color) {
UIUtil.drawBoldDottedLine(g, startX, endX, startY, null, color, false);
UIUtil.drawBoldDottedLine(g, startX, endX, bottomY, null, color, false);
}
@@ -102,8 +102,9 @@ public class DiffUtil {
UIUtil.drawLine(g, startX, y + 1, endX, y + 1, null, color);
}
- public static Color getFramingColor(@NotNull Color backgroundColor) {
- return backgroundColor.darker();
+ @Nullable
+ public static Color getFramingColor(@Nullable Color backgroundColor) {
+ return backgroundColor != null ? backgroundColor.darker() : null;
}
@NotNull
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 d3b273fdaba9..7e395c1b4a9e 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
@@ -137,7 +137,8 @@ public class FragmentedDiffPanelState extends DiffPanelState {
//setDiffPolicy(diffPolicy);
diffPolicy.setRanges(ranges);
- return addMarkup(new TextCompareProcessor(myComparisonPolicy, diffPolicy).process(myAppender1.getText(), myAppender2.getText()));
+ return addMarkup(
+ new TextCompareProcessor(myComparisonPolicy, diffPolicy, myHighlightMode).process(myAppender1.getText(), myAppender2.getText()));
}
private BeforeAfter<Integer> lineStarts(int i) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/PresetBlocksDiffPolicy.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/PresetBlocksDiffPolicy.java
index db11ed063c7e..3fd7df130e45 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/PresetBlocksDiffPolicy.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/PresetBlocksDiffPolicy.java
@@ -15,11 +15,14 @@
*/
package com.intellij.openapi.diff.impl.highlighting;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.processing.DiffPolicy;
import com.intellij.openapi.util.TextRange;
import com.intellij.util.BeforeAfter;
import com.intellij.util.diff.FilesTooBigForDiffException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
import java.util.ArrayList;
import java.util.Arrays;
@@ -33,19 +36,28 @@ import java.util.List;
public class PresetBlocksDiffPolicy implements DiffPolicy {
// fragment _start_ offsets
private List<BeforeAfter<TextRange>> myRanges;
- private final DiffPolicy myDelegate;
+ @NotNull private final DiffPolicy myDelegate;
- public PresetBlocksDiffPolicy(DiffPolicy delegate) {
+ public PresetBlocksDiffPolicy(@NotNull DiffPolicy delegate) {
myDelegate = delegate;
}
+ @TestOnly
+ @NotNull
@Override
- public DiffFragment[] buildFragments(String text1, String text2) throws FilesTooBigForDiffException {
+ public DiffFragment[] buildFragments(@NotNull String text1, @NotNull String text2) throws FilesTooBigForDiffException {
+ return buildFragments(DiffString.create(text1), DiffString.create(text2));
+ }
+
+ @NotNull
+ @Override
+ public DiffFragment[] buildFragments(@NotNull DiffString text1, @NotNull DiffString text2) throws FilesTooBigForDiffException {
final List<DiffFragment> fragments = new ArrayList<DiffFragment>();
for (int i = 0; i < myRanges.size(); i++) {
final BeforeAfter<TextRange> range = myRanges.get(i);
- fragments.addAll(Arrays.asList(myDelegate.buildFragments(new String(text1.substring(range.getBefore().getStartOffset(), range.getBefore().getEndOffset())),
- new String(text2.substring(range.getAfter().getStartOffset(), range.getAfter().getEndOffset())))));
+ fragments.addAll(Arrays.asList(myDelegate.buildFragments(
+ text1.substring(range.getBefore().getStartOffset(), range.getBefore().getEndOffset()).copy(),
+ text2.substring(range.getAfter().getStartOffset(), range.getAfter().getEndOffset()).copy())));
}
return fragments.toArray(new DiffFragment[fragments.size()]);
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java
index 14c235470347..d3e1dfd5a64a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java
@@ -30,8 +30,8 @@ import com.intellij.util.diff.FilesTooBigForDiffException;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Iterator;
+import java.util.List;
public abstract class SimpleDiffPanelState implements Disposable {
protected ComparisonPolicy myComparisonPolicy = ComparisonPolicy.DEFAULT;
@@ -84,7 +84,7 @@ public abstract class SimpleDiffPanelState implements Disposable {
public void dispose() {
}
- private LineBlocks addMarkup(final ArrayList<LineFragment> lines) {
+ private LineBlocks addMarkup(final List<LineFragment> lines) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
final FragmentHighlighterImpl fragmentHighlighter = new FragmentHighlighterImpl(myAppender1, myAppender2);
@@ -114,12 +114,8 @@ public abstract class SimpleDiffPanelState implements Disposable {
return LineBlocks.EMPTY;
}
- if (myHighlightMode == HighlightMode.NO_HIGHLIGHTING) {
- return LineBlocks.fromLineFragments(Collections.<LineFragment>emptyList());
- }
-
- return addMarkup(new TextCompareProcessor(myComparisonPolicy, myDiffPolicy, myHighlightMode == HighlightMode.BY_WORD)
- .process(myAppender1.getText(), myAppender2.getText()));
+ return addMarkup(
+ new TextCompareProcessor(myComparisonPolicy, myDiffPolicy, myHighlightMode).process(myAppender1.getText(), myAppender2.getText()));
}
public Project getProject() { return myProject; }
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeList.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeList.java
index dc0e98e722fb..bbd8c929c203 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeList.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeList.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.diff.impl.incrementalMerge;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.ComparisonPolicy;
import com.intellij.openapi.diff.impl.DiffUtil;
@@ -29,6 +30,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import com.intellij.util.diff.FilesTooBigForDiffException;
+import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -108,12 +110,12 @@ public class ChangeList {
private ArrayList<Change> buildChanges() throws FilesTooBigForDiffException {
Document base = getDocument(FragmentSide.SIDE1);
- String[] baseLines = DiffUtil.convertToLines(base.getText());
+ DiffString[] baseLines = DiffUtil.convertToLines(base.getText());
Document version = getDocument(FragmentSide.SIDE2);
- String[] versionLines = DiffUtil.convertToLines(version.getText());
+ DiffString[] versionLines = DiffUtil.convertToLines(version.getText());
DiffFragment[] fragments = ComparisonPolicy.DEFAULT.buildDiffFragmentsFromLines(baseLines, versionLines);
final ArrayList<Change> result = new ArrayList<Change>();
- new DiffFragmemntsEnumerator(fragments) {
+ new DiffFragmentsEnumerator(fragments) {
protected void process(DiffFragment fragment) {
if (fragment.isEqual()) return;
Context context = getContext();
@@ -129,11 +131,11 @@ public class ChangeList {
return myChanges.get(index);
}
- private abstract static class DiffFragmemntsEnumerator {
+ private abstract static class DiffFragmentsEnumerator {
private final DiffFragment[] myFragments;
private final Context myContext;
- private DiffFragmemntsEnumerator(DiffFragment[] fragments) {
+ private DiffFragmentsEnumerator(DiffFragment[] fragments) {
myContext = new Context();
myFragments = fragments;
}
@@ -142,8 +144,8 @@ public class ChangeList {
for (DiffFragment fragment : myFragments) {
myContext.myFragment = fragment;
process(fragment);
- String text1 = fragment.getText1();
- String text2 = fragment.getText2();
+ DiffString text1 = fragment.getText1();
+ DiffString text2 = fragment.getText2();
myContext.myStarts[0] += StringUtil.length(text1);
myContext.myStarts[1] += StringUtil.length(text2);
myContext.myLines[0] += countLines(text1);
@@ -151,7 +153,7 @@ public class ChangeList {
}
}
- private static int countLines(String text) {
+ private static int countLines(@Nullable DiffString text) {
if (text == null) return 0;
return StringUtil.countNewLines(text);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java
index 2c1b1e267b15..d3a0b5a50d58 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.DiffBundle;
import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.DiffRequest;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
import com.intellij.openapi.diff.impl.incrementalMerge.ui.MergePanel2;
@@ -149,8 +150,8 @@ public class MergeList implements UserDataHolder {
@NotNull String baseText,
@NotNull String rightText,
@NotNull ContextLogger logger) throws FilesTooBigForDiffException {
- DiffFragment[] leftFragments = DiffPolicy.DEFAULT_LINES.buildFragments(baseText, leftText);
- DiffFragment[] rightFragments = DiffPolicy.DEFAULT_LINES.buildFragments(baseText, rightText);
+ DiffFragment[] leftFragments = DiffPolicy.DEFAULT_LINES.buildFragments(DiffString.create(baseText), DiffString.create(leftText));
+ DiffFragment[] rightFragments = DiffPolicy.DEFAULT_LINES.buildFragments(DiffString.create(baseText), DiffString.create(rightText));
int[] leftOffsets = {0, 0};
int[] rightOffsets = {0, 0};
int leftIndex = 0;
@@ -188,7 +189,7 @@ public class MergeList implements UserDataHolder {
leftOffsets[1] += versionLength;
}
- private static int getTextLength(@Nullable String text1) {
+ private static int getTextLength(@Nullable DiffString text1) {
return text1 != null ? text1.length() : 0;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/PreferWholeLines.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/PreferWholeLines.java
index 2a6a01c10414..2d41620f6de2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/PreferWholeLines.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/PreferWholeLines.java
@@ -18,35 +18,47 @@ package com.intellij.openapi.diff.impl.processing;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.util.text.StringUtil;
class PreferWholeLines implements DiffCorrection {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.PreferWholeLines");
public static final DiffCorrection INSTANCE = new PreferWholeLines();
+
public DiffFragment[] correct(DiffFragment[] fragments) {
for (int i = 1; i < fragments.length - 1; i++) {
DiffFragment fragment = fragments[i];
if (!fragment.isOneSide()) continue;
DiffFragment nextFragment = fragments[i + 1];
FragmentSide side = FragmentSide.chooseSide(fragment);
+
+ DiffString fragmentText = side.getText(fragment);
+ DiffString otherNextFragmentText = side.getOtherText(nextFragment);
+ DiffString nextFragmentText = side.getText(nextFragment);
+
if (nextFragment.isOneSide()) {
- LOG.error("<" + side.getText(fragment) + "> <" + side.getOtherText(nextFragment) + ">");
+ LOG.error("<" + fragmentText + "> <" + otherNextFragmentText + ">");
}
- if (StringUtil.startsWithChar(side.getText(fragment), '\n') &&
- StringUtil.startsWithChar(side.getText(nextFragment), '\n') &&
- StringUtil.startsWithChar(side.getOtherText(nextFragment), '\n')) {
+ if (StringUtil.startsWithChar(fragmentText, '\n') &&
+ StringUtil.startsWithChar(nextFragmentText, '\n') &&
+ StringUtil.startsWithChar(otherNextFragmentText, '\n')) {
+
DiffFragment previous = fragments[i - 1];
- previous = side.createFragment(side.getText(previous) + "\n",
- side.getOtherText(previous) + "\n",
- previous.isModified());
+ DiffString previousText = side.getText(previous);
+ DiffString otherPreciousText = side.getOtherText(previous);
+
+ assert previous != null;
+ assert previousText != null;
+ assert otherPreciousText != null;
+ assert fragmentText != null;
+ assert nextFragmentText != null;
+ assert otherNextFragmentText != null;
+
+ previous = side.createFragment(previousText.append('\n'), otherPreciousText.append('\n'), previous.isModified());
fragments[i - 1] = previous;
- fragment = side.createFragment(side.getText(fragment).substring(1) + "\n",
- side.getOtherText(fragment),
- fragment.isModified());
+ fragment = side.createFragment(fragmentText.substring(1).append('\n'), side.getOtherText(fragment), fragment.isModified());
fragments[i] = fragment;
- nextFragment = side.createFragment(side.getText(nextFragment).substring(1),
- side.getOtherText(nextFragment).substring(1),
- nextFragment.isModified());
+ nextFragment = side.createFragment(nextFragmentText.substring(1), otherNextFragmentText.substring(1), nextFragment.isModified());
fragments[i + 1] = nextFragment;
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java
index e527964a5c0d..1ae503e06d64 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java
@@ -23,53 +23,59 @@ import com.intellij.openapi.diff.impl.fragments.LineFragment;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
import com.intellij.openapi.diff.impl.highlighting.LineBlockDivider;
import com.intellij.openapi.diff.impl.highlighting.Util;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.diff.FilesTooBigForDiffException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
public class TextCompareProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.Processor");
- private final DiffPolicy myDiffPolicy;
@NotNull private final ComparisonPolicy myComparisonPolicy;
- private final boolean mySearchForSubFragments;
+ @NotNull private final DiffPolicy myDiffPolicy;
+ @NotNull private final HighlightMode myHighlightMode;
public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy,
- final DiffPolicy diffPolicy,
- boolean searchForSubFragments) {
+ @NotNull DiffPolicy diffPolicy,
+ @NotNull HighlightMode highlightMode) {
myComparisonPolicy = comparisonPolicy;
myDiffPolicy = diffPolicy;
- mySearchForSubFragments = searchForSubFragments;
- }
-
- public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy, final DiffPolicy diffPolicy) {
- this(comparisonPolicy, diffPolicy, true);
+ myHighlightMode = highlightMode;
}
public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy) {
- this(comparisonPolicy, DiffPolicy.LINES_WO_FORMATTING);
+ this(comparisonPolicy, DiffPolicy.LINES_WO_FORMATTING, HighlightMode.BY_WORD);
}
- public ArrayList<LineFragment> process(@Nullable String text1, @Nullable String text2) throws FilesTooBigForDiffException {
+ public List<LineFragment> process(@Nullable String text1, @Nullable String text2) throws FilesTooBigForDiffException {
+ if (myHighlightMode == HighlightMode.NO_HIGHLIGHTING) {
+ return Collections.emptyList();
+ }
+
text1 = StringUtil.notNullize(text1);
text2 = StringUtil.notNullize(text2);
if (text1.isEmpty() || text2.isEmpty()) {
return new DummyDiffFragmentsProcessor().process(text1, text2);
}
- DiffFragment[] woFormattingBlocks = myDiffPolicy.buildFragments(text1, text2);
+ DiffString diffText1 = DiffString.create(text1);
+ DiffString diffText2 = DiffString.create(text2);
+
+ DiffFragment[] woFormattingBlocks = myDiffPolicy.buildFragments(diffText1, diffText2);
DiffFragment[] step1lineFragments = new DiffCorrection.TrueLineBlocks(myComparisonPolicy).correctAndNormalize(woFormattingBlocks);
ArrayList<LineFragment> lineBlocks = new DiffFragmentsProcessor().process(step1lineFragments);
int badLinesCount = 0;
- if (mySearchForSubFragments) {
+ if (myHighlightMode == HighlightMode.BY_WORD) {
for (LineFragment lineBlock : lineBlocks) {
if (lineBlock.isOneSide() || lineBlock.isEqual()) continue;
try {
- String subText1 = lineBlock.getText(text1, FragmentSide.SIDE1);
- String subText2 = lineBlock.getText(text2, FragmentSide.SIDE2);
+ DiffString subText1 = lineBlock.getText(diffText1, FragmentSide.SIDE1);
+ DiffString subText2 = lineBlock.getText(diffText2, FragmentSide.SIDE2);
ArrayList<LineFragment> subFragments = findSubFragments(subText1, subText2);
lineBlock.setChildren(new ArrayList<Fragment>(subFragments));
lineBlock.adjustTypeFromChildrenTypes();
@@ -84,7 +90,7 @@ public class TextCompareProcessor {
return lineBlocks;
}
- private ArrayList<LineFragment> findSubFragments(String text1, String text2) throws FilesTooBigForDiffException {
+ private ArrayList<LineFragment> findSubFragments(@NotNull DiffString text1, @NotNull DiffString text2) throws FilesTooBigForDiffException {
DiffFragment[] fragments = new ByWord(myComparisonPolicy).buildFragments(text1, text2);
fragments = DiffCorrection.ConnectSingleSideToChange.INSTANCE.correct(fragments);
fragments = UniteSameType.INSTANCE.correct(fragments);
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/DividerPolygon.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/DividerPolygon.java
index 33db73f3a8eb..6e6a60702595 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/DividerPolygon.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/DividerPolygon.java
@@ -23,6 +23,8 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.util.Comparing;
import com.intellij.util.ui.GraphicsUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.awt.geom.CubicCurve2D;
@@ -34,7 +36,7 @@ import java.util.ArrayList;
*/
public class DividerPolygon {
- private final Color myColor;
+ @Nullable private final Color myColor;
private final int myStart1;
private final int myStart2;
private final int myEnd1;
@@ -43,7 +45,7 @@ public class DividerPolygon {
public static final double CTRL_PROXIMITY_X = 0.3;
- public DividerPolygon(int start1, int start2, int end1, int end2, Color color, boolean applied) {
+ public DividerPolygon(int start1, int start2, int end1, int end2, @Nullable Color color, boolean applied) {
myApplied = applied;
myStart1 = advance(start1);
myStart2 = advance(start2);
@@ -150,7 +152,9 @@ public class DividerPolygon {
//g.setComposite(composite);
}
- public static ArrayList<DividerPolygon> createVisiblePolygons(EditingSides sides, FragmentSide left, int diffDividerPolygonsOffset) {
+ public static ArrayList<DividerPolygon> createVisiblePolygons(@NotNull EditingSides sides,
+ @NotNull FragmentSide left,
+ int diffDividerPolygonsOffset) {
Editor editor1 = sides.getEditor(left);
Editor editor2 = sides.getEditor(left.otherSide());
LineBlocks lineBlocks = sides.getLineBlocks();
@@ -174,7 +178,10 @@ public class DividerPolygon {
return new FoldingTransformation(editor);
}
- private static DividerPolygon createPolygon(Transformation[] transformations, Trapezium trapezium, Color color, FragmentSide left,
+ private static DividerPolygon createPolygon(@NotNull Transformation[] transformations,
+ @NotNull Trapezium trapezium,
+ @Nullable Color color,
+ @NotNull FragmentSide left,
int diffDividerPolygonsOffset, boolean applied) {
Interval base1 = trapezium.getBase(left);
Interval base2 = trapezium.getBase(left.otherSide());
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java
index e169a9c20e81..f6cd904c9503 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java
@@ -26,7 +26,7 @@ import com.intellij.openapi.editor.ScrollingModel;
import com.intellij.openapi.editor.event.VisibleAreaEvent;
import com.intellij.openapi.editor.event.VisibleAreaListener;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
@@ -35,7 +35,7 @@ import java.util.ArrayList;
public class SyncScrollSupport implements Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.util.SyncScrollSupport");
private boolean myDuringVerticalScroll = false;
- private final ArrayList<ScrollListener> myScrollers = new ArrayList<ScrollListener>();
+ @NotNull private final ArrayList<ScrollListener> myScrollers = new ArrayList<ScrollListener>();
private boolean myEnabled = true;
public void install(EditingSides[] sideContainers) {
@@ -67,34 +67,34 @@ public class SyncScrollSupport implements Disposable {
return myEnabled;
}
- private void install2(Editor[] editors, EditingSides[] sideContainers) {
- addSlavesScroller(editors[0], new Pair<FragmentSide, EditingSides>(FragmentSide.SIDE1, sideContainers[0]));
- addSlavesScroller(editors[1], new Pair<FragmentSide, EditingSides>(FragmentSide.SIDE2, sideContainers[0]));
+ private void install2(@NotNull Editor[] editors, @NotNull EditingSides[] sideContainers) {
+ addSlavesScroller(editors[0], new ScrollingContext(FragmentSide.SIDE1, sideContainers[0], FragmentSide.SIDE1));
+ addSlavesScroller(editors[1], new ScrollingContext(FragmentSide.SIDE2, sideContainers[0], FragmentSide.SIDE2));
}
- private void install3(Editor[] editors, EditingSides[] sideContainers) {
+ private void install3(@NotNull Editor[] editors, @NotNull EditingSides[] sideContainers) {
addSlavesScroller(editors[0],
- new Pair<FragmentSide, EditingSides>(FragmentSide.SIDE1, sideContainers[0]),
- new Pair<FragmentSide, EditingSides>(FragmentSide.SIDE1, sideContainers[1]));
+ new ScrollingContext(FragmentSide.SIDE1, sideContainers[0], FragmentSide.SIDE2),
+ new ScrollingContext(FragmentSide.SIDE1, sideContainers[1], FragmentSide.SIDE1));
addSlavesScroller(editors[1],
- new Pair<FragmentSide, EditingSides>(FragmentSide.SIDE2, sideContainers[0]),
- new Pair<FragmentSide, EditingSides>(FragmentSide.SIDE1, sideContainers[1]));
+ new ScrollingContext(FragmentSide.SIDE2, sideContainers[0], FragmentSide.SIDE1),
+ new ScrollingContext(FragmentSide.SIDE1, sideContainers[1], FragmentSide.SIDE1));
addSlavesScroller(editors[2],
- new Pair<FragmentSide, EditingSides>(FragmentSide.SIDE2, sideContainers[1]),
- new Pair<FragmentSide, EditingSides>(FragmentSide.SIDE2, sideContainers[0]));
+ new ScrollingContext(FragmentSide.SIDE2, sideContainers[1], FragmentSide.SIDE2),
+ new ScrollingContext(FragmentSide.SIDE2, sideContainers[0], FragmentSide.SIDE1));
}
- private void addSlavesScroller(Editor editor, Pair<FragmentSide, EditingSides>... contexts) {
+ private void addSlavesScroller(@NotNull Editor editor, @NotNull ScrollingContext... contexts) {
ScrollListener scroller = new ScrollListener(contexts, editor);
scroller.install();
myScrollers.add(scroller);
}
private class ScrollListener implements VisibleAreaListener, Disposable {
- private Pair<FragmentSide, EditingSides>[] myScrollContexts;
- private final Editor myEditor;
+ private ScrollingContext[] myScrollContexts;
+ @NotNull private final Editor myEditor;
- public ScrollListener(Pair<FragmentSide, EditingSides>[] scrollContexts, Editor editor) {
+ public ScrollListener(@NotNull ScrollingContext[] scrollContexts, @NotNull Editor editor) {
myScrollContexts = scrollContexts;
myEditor = editor;
}
@@ -103,11 +103,13 @@ public class SyncScrollSupport implements Disposable {
myEditor.getScrollingModel().addVisibleAreaListener(this);
}
+ @Override
public void dispose() {
myEditor.getScrollingModel().removeVisibleAreaListener(this);
myScrollContexts = null;
}
+ @Override
public void visibleAreaChanged(VisibleAreaEvent e) {
if (!myEnabled || myDuringVerticalScroll) return;
Rectangle newRectangle = e.getNewRectangle();
@@ -115,7 +117,7 @@ public class SyncScrollSupport implements Disposable {
if (newRectangle == null || oldRectangle == null) return;
myDuringVerticalScroll = true;
try {
- for (Pair<FragmentSide, EditingSides> context : myScrollContexts) {
+ for (ScrollingContext context : myScrollContexts) {
syncVerticalScroll(context, newRectangle, oldRectangle);
syncHorizontalScroll(context, newRectangle, oldRectangle);
}
@@ -124,11 +126,13 @@ public class SyncScrollSupport implements Disposable {
}
}
- private static void syncHorizontalScroll(Pair<FragmentSide,EditingSides> context, Rectangle newRectangle, Rectangle oldRectangle) {
+ private static void syncHorizontalScroll(@NotNull ScrollingContext context,
+ @NotNull Rectangle newRectangle,
+ @NotNull Rectangle oldRectangle) {
int newScrollOffset = newRectangle.x;
if (newScrollOffset == oldRectangle.x) return;
- EditingSides sidesContainer = context.getSecond();
- FragmentSide masterSide = context.getFirst();
+ EditingSides sidesContainer = context.getSidesContainer();
+ FragmentSide masterSide = context.getMasterSide();
Editor slaveEditor = sidesContainer.getEditor(masterSide.otherSide());
if (slaveEditor == null) return;
@@ -138,10 +142,13 @@ public class SyncScrollSupport implements Disposable {
scrollingModel.enableAnimation();
}
- private static void syncVerticalScroll(Pair<FragmentSide,EditingSides> context, Rectangle newRectangle, Rectangle oldRectangle) {
+ private static void syncVerticalScroll(@NotNull ScrollingContext context,
+ @NotNull Rectangle newRectangle,
+ @NotNull Rectangle oldRectangle) {
if (newRectangle.y == oldRectangle.y && newRectangle.height == oldRectangle.height) return;
- EditingSides sidesContainer = context.getSecond();
- FragmentSide masterSide = context.getFirst();
+ EditingSides sidesContainer = context.getSidesContainer();
+ FragmentSide masterSide = context.getMasterSide();
+ FragmentSide masterDiffSide = context.getMasterDiffSide();
Editor master = sidesContainer.getEditor(masterSide);
Editor slave = sidesContainer.getEditor(masterSide.otherSide());
@@ -159,7 +166,7 @@ public class SyncScrollSupport implements Disposable {
if (masterCenterLine > master.getDocument().getLineCount()) {
masterCenterLine = master.getDocument().getLineCount();
}
- int scrollToLine = sidesContainer.getLineBlocks().transform(masterSide, masterCenterLine) + 1;
+ int scrollToLine = sidesContainer.getLineBlocks().transform(masterDiffSide, masterCenterLine) + 1;
int actualLine = scrollToLine - 1;
@@ -179,18 +186,45 @@ public class SyncScrollSupport implements Disposable {
}
}
- private static int getScrollOffset(final Editor editor) {
+ private static int getScrollOffset(@NotNull final Editor editor) {
final JComponent header = editor.getHeaderComponent();
int headerOffset = header == null ? 0 : header.getHeight();
return editor.getScrollingModel().getVerticalScrollOffset() - headerOffset;
}
- public static void scrollEditor(Editor editor, int logicalLine) {
+ public static void scrollEditor(@NotNull Editor editor, int logicalLine) {
editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(logicalLine, 0));
ScrollingModel scrollingModel = editor.getScrollingModel();
scrollingModel.disableAnimation();
scrollingModel.scrollToCaret(ScrollType.CENTER);
scrollingModel.enableAnimation();
}
+
+ private static class ScrollingContext {
+ @NotNull private final EditingSides mySidesContainer;
+ @NotNull private final FragmentSide myMasterSide;
+ @NotNull private final FragmentSide myMasterDiffSide;
+
+ public ScrollingContext(@NotNull FragmentSide masterSide, @NotNull EditingSides sidesContainer, @NotNull FragmentSide masterDiffSide) {
+ mySidesContainer = sidesContainer;
+ myMasterSide = masterSide;
+ myMasterDiffSide = masterDiffSide;
+ }
+
+ @NotNull
+ public EditingSides getSidesContainer() {
+ return mySidesContainer;
+ }
+
+ @NotNull
+ public FragmentSide getMasterSide() {
+ return myMasterSide;
+ }
+
+ @NotNull
+ public FragmentSide getMasterDiffSide() {
+ return myMasterDiffSide;
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/CutAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/CutAction.java
index 4fc378e566c6..dd54b1de2087 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/CutAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/CutAction.java
@@ -53,12 +53,7 @@ public class CutAction extends EditorAction {
});
}
editor.getSelectionModel().copySelectionToClipboard();
- editor.getCaretModel().runForEachCaret(new CaretAction() {
- @Override
- public void perform(Caret caret) {
- EditorModificationUtil.deleteSelectedText(editor);
- }
- });
+ EditorModificationUtil.deleteSelectedTextForAllCarets(editor);
}
}
} \ No newline at end of file
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 16b66768d791..bc3b85bfce95 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
@@ -50,7 +50,7 @@ public class EscapeAction extends EditorAction {
public boolean isEnabled(Editor editor, DataContext dataContext) {
SelectionModel selectionModel = editor.getSelectionModel();
CaretModel caretModel = editor.getCaretModel();
- return selectionModel.hasSelection() || selectionModel.hasBlockSelection() || caretModel.getAllCarets().size() > 1;
+ return selectionModel.hasSelection() || selectionModel.hasBlockSelection() || caretModel.getCaretCount() > 1;
}
}
}
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 1883cb55387c..182884b25020 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
@@ -49,13 +49,19 @@ class MoveCaretLeftOrRightHandler extends EditorActionHandler {
int start = selectionModel.getSelectionStart();
int end = selectionModel.getSelectionEnd();
int caretOffset = caretModel.getOffset();
+ VisualPosition targetPosition = myDirection == Direction.RIGHT ? selectionModel.getSelectionEndPosition() : selectionModel.getSelectionStartPosition();
//int leftGuard = start + (myDirection == Direction.LEFT ? 1 : 0);
//int rightGuard = end - (myDirection == Direction.RIGHT ? 1 : 0);
//if (TextRange.from(leftGuard, rightGuard - leftGuard + 1).contains(caretModel.getOffset())) { // See IDEADEV-36957
if (start <= caretOffset && end >= caretOffset) { // See IDEADEV-36957
selectionModel.removeSelection();
- caretModel.moveToOffset(myDirection == Direction.RIGHT ? end : start);
+ if (caretModel.supportsMultipleCarets() && editor.isColumnMode() && targetPosition != null) {
+ caretModel.moveToVisualPosition(targetPosition);
+ }
+ else {
+ caretModel.moveToOffset(myDirection == Direction.RIGHT ? end : start);
+ }
scrollingModel.scrollToCaret(ScrollType.RELATIVE);
return;
}
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 012410d34fe3..41a833b3bffb 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
@@ -806,6 +806,15 @@ public final class EditorUtil {
int line = y / editor.getLineHeight();
return line > 0 ? editor.visualToLogicalPosition(new VisualPosition(line, 0)).line : 0;
}
+
+ public static boolean isAtLineEnd(@NotNull Editor editor, int offset) {
+ Document document = editor.getDocument();
+ if (offset < 0 || offset > document.getTextLength()) {
+ return false;
+ }
+ int line = document.getLineNumber(offset);
+ return offset == document.getLineEndOffset(line);
+ }
}
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 1b79d356cfb6..f6f030c67ee8 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
@@ -94,6 +94,10 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
private int startBefore;
private int endBefore;
boolean myUnknownDirection;
+ // offsets of selection start/end position relative to end of line - can be non-zero in column selection mode
+ // these are non-negative values, myStartVirtualOffset is always less or equal to myEndVirtualOffset
+ private int myStartVirtualOffset;
+ private int myEndVirtualOffset;
CaretImpl(EditorImpl editor) {
myEditor = editor;
@@ -144,10 +148,18 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
if (marker.isValid()) {
startAfter = marker.getStartOffset();
endAfter = marker.getEndOffset();
+ if (myEndVirtualOffset > 0 && (!isVirtualSelectionEnabled()
+ || !EditorUtil.isAtLineEnd(myEditor, endAfter)
+ || myEditor.getDocument().getLineNumber(startAfter) != myEditor.getDocument().getLineNumber(endAfter))) {
+ myStartVirtualOffset = 0;
+ myEndVirtualOffset = 0;
+ }
}
else {
startAfter = endAfter = getOffset();
marker.release();
+ myStartVirtualOffset = 0;
+ myEndVirtualOffset = 0;
mySelectionMarker = null;
}
@@ -235,7 +247,8 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
public void run() {
SelectionModelImpl selectionModel = myEditor.getSelectionModel();
- final int leadSelectionOffset = selectionModel.getLeadSelectionOffset();
+ final int leadSelectionOffset = getLeadSelectionOffset();
+ final VisualPosition leadSelectionPosition = getLeadSelectionPosition();
LogicalPosition blockSelectionStart = selectionModel.hasBlockSelection()
? selectionModel.getBlockStart()
: getLogicalPosition();
@@ -349,24 +362,43 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
}
else {
if (selectToDocumentStart) {
- selectionModel.setSelection(leadSelectionOffset, 0);
+ if (myEditor.getCaretModel().supportsMultipleCarets()) {
+ setSelection(leadSelectionPosition, leadSelectionOffset, myEditor.offsetToVisualPosition(0), 0);
+ }
+ else {
+ setSelection(leadSelectionOffset, 0);
+ }
}
else if (pos.line >= myEditor.getVisibleLineCount()) {
- if (leadSelectionOffset < document.getTextLength()) {
- selectionModel.setSelection(leadSelectionOffset, document.getTextLength());
+ int endOffset = document.getTextLength();
+ if (leadSelectionOffset < endOffset) {
+ if (myEditor.getCaretModel().supportsMultipleCarets()) {
+ setSelection(leadSelectionPosition, leadSelectionOffset, myEditor.offsetToVisualPosition(endOffset), endOffset);
+ }
+ else {
+ setSelection(leadSelectionOffset, endOffset);
+ }
}
}
else {
int selectionStartToUse = leadSelectionOffset;
- if (selectionModel.isUnknownDirection()) {
- if (getOffset() > leadSelectionOffset) {
- selectionStartToUse = Math.min(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
+ VisualPosition selectionStartPositionToUse = leadSelectionPosition;
+ if (isUnknownDirection()) {
+ if (getOffset() > leadSelectionOffset ^ getSelectionStart() < getSelectionEnd()) {
+ selectionStartToUse = getSelectionEnd();
+ selectionStartPositionToUse = getSelectionEndPosition();
}
else {
- selectionStartToUse = Math.max(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
+ selectionStartToUse = getSelectionStart();
+ selectionStartPositionToUse = getSelectionStartPosition();
}
}
- selectionModel.setSelection(selectionStartToUse, getVisualPosition(), getOffset());
+ if (myEditor.getCaretModel().supportsMultipleCarets()) {
+ setSelection(selectionStartPositionToUse, selectionStartToUse, getVisualPosition(), getOffset());
+ }
+ else {
+ setSelection(selectionStartToUse, getVisualPosition(), getOffset());
+ }
}
}
}
@@ -933,22 +965,32 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
int lineShift = above ? -1 : 1;
final CaretImpl clone = cloneWithoutSelection();
final int newSelectionStartOffset, newSelectionEndOffset;
+ final VisualPosition newSelectionStartPosition, newSelectionEndPosition;
final boolean hasNewSelection;
if (hasSelection()) {
- LogicalPosition selectionStart = myEditor.offsetToLogicalPosition(getSelectionStart());
- LogicalPosition selectionEnd = myEditor.offsetToLogicalPosition(getSelectionEnd());
- LogicalPosition newSelectionStart = new LogicalPosition(selectionStart.line + lineShift, selectionStart.column);
- LogicalPosition newSelectionEnd = new LogicalPosition(selectionEnd.line + lineShift, selectionEnd.column);
- newSelectionStartOffset = getTruncatedOffset(newSelectionStart);
- newSelectionEndOffset = getTruncatedOffset(newSelectionEnd);
- hasNewSelection = newSelectionStartOffset != newSelectionEndOffset;
+ VisualPosition startPosition = getSelectionStartPosition();
+ VisualPosition endPosition = getSelectionEndPosition();
+ VisualPosition leadPosition = getLeadSelectionPosition();
+ boolean leadIsStart = leadPosition.equals(startPosition);
+ boolean leadIsEnd = leadPosition.equals(endPosition);
+ LogicalPosition selectionStart = myEditor.visualToLogicalPosition(leadIsStart || leadIsEnd ? leadPosition : startPosition);
+ LogicalPosition selectionEnd = myEditor.visualToLogicalPosition(leadIsEnd ? startPosition : endPosition);
+ LogicalPosition newSelectionStart = truncate(new LogicalPosition(selectionStart.line + lineShift, selectionStart.column));
+ LogicalPosition newSelectionEnd = truncate(new LogicalPosition(selectionEnd.line + lineShift, selectionEnd.column));
+ newSelectionStartOffset = myEditor.logicalPositionToOffset(newSelectionStart);
+ newSelectionEndOffset = myEditor.logicalPositionToOffset(newSelectionEnd);
+ newSelectionStartPosition = myEditor.logicalToVisualPosition(newSelectionStart);
+ newSelectionEndPosition = myEditor.logicalToVisualPosition(newSelectionEnd);
+ hasNewSelection = !newSelectionStart.equals(newSelectionEnd);
}
else {
newSelectionStartOffset = 0;
newSelectionEndOffset = 0;
+ newSelectionStartPosition = null;
+ newSelectionEndPosition = null;
hasNewSelection = false;
}
- LogicalPosition oldPosition = hasSelection() && !hasNewSelection ? myEditor.offsetToLogicalPosition(getSelectionStart()) : getLogicalPosition();
+ LogicalPosition oldPosition = getLogicalPosition();
int newLine = oldPosition.line + lineShift;
if (newLine < 0 || newLine >= myEditor.getDocument().getLineCount()) {
Disposer.dispose(clone);
@@ -956,11 +998,11 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
}
clone.moveToLogicalPosition(new LogicalPosition(newLine, oldPosition.column), false, null, false);
if (myEditor.getCaretModel().addCaret(clone)) {
- if (hasSelection() && hasNewSelection) {
+ if (hasNewSelection) {
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
@Override
public void run() {
- clone.setSelection(Math.min(newSelectionStartOffset, newSelectionEndOffset), Math.max(newSelectionStartOffset, newSelectionEndOffset));
+ clone.setSelection(newSelectionStartPosition, newSelectionStartOffset, newSelectionEndPosition, newSelectionEndOffset);
}
});
if (!clone.isValid()) {
@@ -976,15 +1018,15 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
}
}
- private int getTruncatedOffset(LogicalPosition position) {
+ private LogicalPosition truncate(LogicalPosition position) {
if (position.line < 0) {
- return 0;
+ return new LogicalPosition(0, 0);
}
else if (position.line >= myEditor.getDocument().getLineCount()) {
- return myEditor.getDocument().getTextLength();
+ return myEditor.offsetToLogicalPosition(myEditor.getDocument().getTextLength());
}
else {
- return myEditor.logicalPositionToOffset(position);
+ return position;
}
}
@@ -1029,18 +1071,21 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
@NotNull
@Override
public VisualPosition getSelectionStartPosition() {
- VisualPosition defaultPosition = myEditor.offsetToVisualPosition(getSelectionStart());
- if (!hasSelection()) {
- return defaultPosition;
+ validateContext(false);
+ VisualPosition position;
+ if (hasSelection() && mySelectionMarker != null) {
+ position = mySelectionMarker.getStartPosition();
+ if (position == null) {
+ position = myEditor.offsetToVisualPosition(mySelectionMarker.getStartOffset());
+ }
}
-
- MyRangeMarker marker = mySelectionMarker;
- if (marker == null) {
- return defaultPosition;
+ else {
+ position = isVirtualSelectionEnabled() ? getVisualPosition() : myEditor.offsetToVisualPosition(getOffset());
}
-
- VisualPosition result = marker.getStartPosition();
- return result == null ? defaultPosition : result;
+ if (hasVirtualSelection()) {
+ position = new VisualPosition(position.line, position.column + myStartVirtualOffset);
+ }
+ return position;
}
@Override
@@ -1058,25 +1103,29 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
@NotNull
@Override
public VisualPosition getSelectionEndPosition() {
- VisualPosition defaultPosition = myEditor.offsetToVisualPosition(getSelectionEnd());
- if (!hasSelection()) {
- return defaultPosition;
+ validateContext(false);
+ VisualPosition position;
+ if (hasSelection() && mySelectionMarker != null) {
+ position = mySelectionMarker.getEndPosition();
+ if (position == null) {
+ position = myEditor.offsetToVisualPosition(mySelectionMarker.getEndOffset());
+ }
}
-
- MyRangeMarker marker = mySelectionMarker;
- if (marker == null) {
- return defaultPosition;
+ else {
+ position = isVirtualSelectionEnabled() ? getVisualPosition() : myEditor.offsetToVisualPosition(getOffset());
}
-
- VisualPosition result = marker.getEndPosition();
- return result == null ? defaultPosition : result;
+ if (hasVirtualSelection()) {
+ position = new VisualPosition(position.line, position.column + myEndVirtualOffset);
+ }
+ return position;
}
@Override
public boolean hasSelection() {
validateContext(false);
MyRangeMarker marker = mySelectionMarker;
- return marker != null && marker.isValid() && marker.getEndOffset() > marker.getStartOffset();
+ return marker != null && marker.isValid() && (marker.getEndOffset() > marker.getStartOffset()
+ || isVirtualSelectionEnabled() && myEndVirtualOffset > myStartVirtualOffset);
}
@Override
@@ -1162,10 +1211,12 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
}
/* Normalize selection */
+ boolean switchedOffsets = false;
if (startOffset > endOffset) {
int tmp = startOffset;
startOffset = endOffset;
endOffset = tmp;
+ switchedOffsets = true;
}
FoldingModelEx foldingModel = myEditor.getFoldingModel();
@@ -1200,6 +1251,8 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
}
marker = new MyRangeMarker((DocumentEx)doc, startOffset, endOffset);
+ myStartVirtualOffset = 0;
+ myEndVirtualOffset = 0;
if (visualPositionAware) {
if (endPosition.after(startPosition)) {
marker.setStartPosition(startPosition);
@@ -1211,6 +1264,17 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
marker.setEndPosition(startPosition);
marker.setEndPositionIsLead(true);
}
+
+ if (isVirtualSelectionEnabled() &&
+ myEditor.getDocument().getLineNumber(startOffset) == myEditor.getDocument().getLineNumber(endOffset)) {
+ int endLineColumn = myEditor.offsetToVisualPosition(endOffset).column;
+ int startDiff =
+ EditorUtil.isAtLineEnd(myEditor, switchedOffsets ? endOffset : startOffset) ? startPosition.column - endLineColumn : 0;
+ int endDiff =
+ EditorUtil.isAtLineEnd(myEditor, switchedOffsets ? startOffset : endOffset) ? endPosition.column - endLineColumn : 0;
+ myStartVirtualOffset = Math.max(0, Math.min(startDiff, endDiff));
+ myEndVirtualOffset = Math.max(0, Math.max(startDiff, endDiff));
+ }
}
mySelectionMarker = marker;
@@ -1248,6 +1312,8 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
int endOffset = marker.getEndOffset();
marker.release();
mySelectionMarker = null;
+ myStartVirtualOffset = 0;
+ myEndVirtualOffset = 0;
myEditor.getSelectionModel().fireSelectionChanged(startOffset, endOffset, caretOffset, caretOffset);
}
}
@@ -1293,17 +1359,36 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
public VisualPosition getLeadSelectionPosition() {
MyRangeMarker marker = mySelectionMarker;
VisualPosition caretPosition = getVisualPosition();
+ if (isVirtualSelectionEnabled() && !hasSelection()) {
+ return caretPosition;
+ }
if (marker == null) {
return caretPosition;
}
if (marker.isEndPositionIsLead()) {
VisualPosition result = marker.getEndPosition();
- return result == null ? getSelectionEndPosition() : result;
+ if (result == null) {
+ return getSelectionEndPosition();
+ }
+ else {
+ if (hasVirtualSelection()) {
+ result = new VisualPosition(result.line, result.column + myEndVirtualOffset);
+ }
+ return result;
+ }
}
else {
VisualPosition result = marker.getStartPosition();
- return result == null ? getSelectionStartPosition() : result;
+ if (result == null) {
+ return getSelectionStartPosition();
+ }
+ else {
+ if (hasVirtualSelection()) {
+ result = new VisualPosition(result.line, result.column + myStartVirtualOffset);
+ }
+ return result;
+ }
}
}
@@ -1367,6 +1452,16 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
}
}
+ private boolean isVirtualSelectionEnabled() {
+ return myEditor.isColumnMode() && myEditor.getCaretModel().supportsMultipleCarets();
+ }
+
+ boolean hasVirtualSelection() {
+ validateContext(false);
+ MyRangeMarker marker = mySelectionMarker;
+ return marker != null && marker.isValid() && isVirtualSelectionEnabled() && myEndVirtualOffset > myStartVirtualOffset;
+ }
+
/**
* 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 72de1c92bbab..ad9e08d4f7f5 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
@@ -31,13 +31,11 @@ import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.editor.event.DocumentEvent;
-import com.intellij.openapi.editor.event.MultipleCaretListener;
import com.intellij.openapi.editor.ex.DocumentBulkUpdateListener;
import com.intellij.openapi.editor.ex.PrioritizedDocumentListener;
import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.EventDispatcher;
import org.jetbrains.annotations.NotNull;
@@ -48,8 +46,7 @@ import java.util.*;
public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener, Disposable {
private final EditorImpl myEditor;
- private final EventDispatcher<MultipleCaretListener> myCaretListeners = EventDispatcher.create(MultipleCaretListener.class);
- private final Map<CaretListener, MultipleCaretListener> myListenerMap = new HashMap<CaretListener, MultipleCaretListener>();
+ private final EventDispatcher<CaretListener> myCaretListeners = EventDispatcher.create(CaretListener.class);
private final boolean mySupportsMultipleCarets = Registry.is("editor.allow.multiple.carets");
private TextAttributes myTextAttributes;
@@ -202,38 +199,12 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
@Override
public void addCaretListener(@NotNull final CaretListener listener) {
- MultipleCaretListener newListener;
- if (listener instanceof MultipleCaretListener) {
- newListener = (MultipleCaretListener)listener;
- }
- else {
- newListener = new MultipleCaretListener() {
- @Override
- public void caretAdded(CaretEvent e) {
-
- }
-
- @Override
- public void caretRemoved(CaretEvent e) {
-
- }
-
- @Override
- public void caretPositionChanged(CaretEvent e) {
- listener.caretPositionChanged(e);
- }
- };
- }
- myListenerMap.put(listener, newListener);
- myCaretListeners.addListener(newListener);
+ myCaretListeners.addListener(listener);
}
@Override
public void removeCaretListener(@NotNull CaretListener listener) {
- MultipleCaretListener newListener = myListenerMap.remove(listener);
- if (newListener != null) {
- myCaretListeners.removeListener(newListener);
- }
+ myCaretListeners.removeListener(listener);
}
@Override
@@ -270,6 +241,13 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
}
@Override
+ public int getCaretCount() {
+ synchronized (myCarets) {
+ return myCarets.size();
+ }
+ }
+
+ @Override
@NotNull
public List<Caret> getAllCarets() {
List<Caret> carets;
@@ -403,8 +381,7 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
}
CaretImpl currCaret = it.next();
if (prevCaret != null && (currCaret.getVisualPosition().equals(prevCaret.getVisualPosition())
- || regionsIntersect(currCaret.getSelectionStart(), currCaret.getSelectionEnd(),
- prevCaret.getSelectionStart(), prevCaret.getSelectionEnd()))) {
+ || selectionsIntersect(currCaret, prevCaret))) {
int newSelectionStart = Math.min(currCaret.getSelectionStart(), prevCaret.getSelectionStart());
int newSelectionEnd = Math.max(currCaret.getSelectionEnd(), prevCaret.getSelectionEnd());
CaretImpl toRetain, toRemove;
@@ -429,10 +406,12 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
}
}
- private static boolean regionsIntersect(int firstStart, int firstEnd, int secondStart, int secondEnd) {
- return firstStart < secondStart && firstEnd > secondStart
- || firstStart > secondStart && firstStart < secondEnd
- || firstStart == secondStart && secondEnd > secondStart && firstEnd > firstStart;
+ private static boolean selectionsIntersect(CaretImpl firstCaret, CaretImpl secondCaret) {
+ return firstCaret.getSelectionStart() < secondCaret.getSelectionStart() && firstCaret.getSelectionEnd() > secondCaret.getSelectionStart()
+ || firstCaret.getSelectionStart() > secondCaret.getSelectionStart() && firstCaret.getSelectionStart() < secondCaret.getSelectionEnd()
+ || firstCaret.getSelectionStart() == secondCaret.getSelectionStart() && secondCaret.getSelectionEnd() > secondCaret.getSelectionStart() && firstCaret.getSelectionEnd() > firstCaret.getSelectionStart()
+ || (firstCaret.getSelectionStart() == firstCaret.getSelectionEnd() && firstCaret.hasVirtualSelection() || secondCaret.getSelectionStart() == secondCaret.getSelectionEnd() && secondCaret.hasVirtualSelection())
+ && (firstCaret.getSelectionStart() == secondCaret.getSelectionStart() || firstCaret.getSelectionEnd() == secondCaret.getSelectionEnd());
}
void doWithCaretMerging(Runnable runnable) {
@@ -452,21 +431,17 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
}
@Override
- public void setCaretsAndSelections(@NotNull final List<LogicalPosition> caretPositions, @NotNull final List<? extends Segment> selections) {
+ public void setCaretsAndSelections(@NotNull final List<CaretState> caretStates) {
myEditor.assertIsDispatchThread();
- if (caretPositions.isEmpty()) {
+ if (caretStates.isEmpty()) {
throw new IllegalArgumentException("At least one caret should exist");
}
- if (caretPositions.size() != selections.size()) {
- throw new IllegalArgumentException("Position and selection lists are of different size");
- }
doWithCaretMerging(new Runnable() {
public void run() {
int index = 0;
int oldCaretCount = myCarets.size();
Iterator<CaretImpl> caretIterator = myCarets.iterator();
- Iterator<? extends Segment> selectionIterator = selections.iterator();
- for (LogicalPosition caretPosition : caretPositions) {
+ for (CaretState caretState : caretStates) {
CaretImpl caret;
boolean caretAdded;
if (index++ < oldCaretCount) {
@@ -475,8 +450,8 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
}
else {
caret = new CaretImpl(myEditor);
- if (caretPosition != null) {
- caret.moveToLogicalPosition(caretPosition, false, null, false);
+ if (caretState != null && caretState.getCaretPosition() != null) {
+ caret.moveToLogicalPosition(caretState.getCaretPosition(), false, null, false);
}
synchronized (myCarets) {
myCarets.add(caret);
@@ -484,15 +459,16 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
fireCaretAdded(caret);
caretAdded = true;
}
- if (caretPosition != null && !caretAdded) {
- caret.moveToLogicalPosition(caretPosition);
+ if (caretState != null && caretState.getCaretPosition() != null && !caretAdded) {
+ caret.moveToLogicalPosition(caretState.getCaretPosition());
}
- Segment selection = selectionIterator.next();
- if (selection != null) {
- caret.setSelection(selection.getStartOffset(), selection.getEndOffset());
+ if (caretState != null && caretState.getSelectionStart() != null && caretState.getSelectionEnd() != null) {
+ caret.setSelection(myEditor.logicalToVisualPosition(caretState.getSelectionStart()), myEditor.logicalPositionToOffset(caretState.getSelectionStart()),
+ myEditor.logicalToVisualPosition(caretState.getSelectionEnd()), myEditor.logicalPositionToOffset(
+ caretState.getSelectionEnd()));
}
}
- int caretsToRemove = myCarets.size() - caretPositions.size();
+ int caretsToRemove = myCarets.size() - caretStates.size();
for (int i = 0; i < caretsToRemove; i++) {
CaretImpl caret;
synchronized (myCarets) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java
index e658e24cb436..611a7c21260d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java
@@ -132,7 +132,14 @@ public class EditorFactoryImpl extends EditorFactory {
@NotNull
public Document createDocument(boolean allowUpdatesWithoutWriteAction) {
- DocumentImpl document = new DocumentImpl("",allowUpdatesWithoutWriteAction);
+ DocumentImpl document = new DocumentImpl("", allowUpdatesWithoutWriteAction);
+ myEditorEventMulticaster.registerDocument(document);
+ return document;
+ }
+
+ @NotNull
+ public Document createDocument(@NotNull CharSequence text, boolean acceptsSlashR, boolean allowUpdatesWithoutWriteAction) {
+ DocumentImpl document = new DocumentImpl(text, acceptsSlashR, allowUpdatesWithoutWriteAction);
myEditorEventMulticaster.registerDocument(document);
return document;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
index 33cebb543c6f..c003d7ba62fa 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
@@ -58,6 +58,7 @@ import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.Function;
import com.intellij.util.IconUtil;
import com.intellij.util.NullableFunction;
+import com.intellij.util.SmartList;
import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.UIUtil;
@@ -401,7 +402,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
return myBackgroundColor;
}
- private boolean isDistractionFreeMode() {
+ private static boolean isDistractionFreeMode() {
return Registry.is("editor.distraction.free.mode");
}
@@ -469,9 +470,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
int patchedStartOffset = startOffset < docLength ? document.getLineStartOffset(document.getLineNumber(startOffset)) : docLength;
int patchedEndOffset = endOffset <= docLength ? document.getLineEndOffset(document.getLineNumber(endOffset)) + 1 : docLength;
DisposableIterator<RangeHighlighterEx> docHighlighters = docMarkup.overlappingIterator(patchedStartOffset, patchedEndOffset);
-
- final MarkupModelEx editorMarkup = (MarkupModelEx)myEditor.getMarkupModel();
- DisposableIterator<RangeHighlighterEx> editorHighlighters = editorMarkup.overlappingIterator(startOffset, endOffset);
+ DisposableIterator<RangeHighlighterEx> editorHighlighters = myEditor.getMarkupModel().overlappingIterator(startOffset, endOffset);
try {
RangeHighlighterEx lastDocHighlighter = null;
@@ -504,7 +503,6 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
if (lastDocHighlighter == null && lastEditorHighlighter == null) return;
final RangeHighlighterEx lowerHighlighter;
-
if (less(lastDocHighlighter, lastEditorHighlighter)) {
lowerHighlighter = lastDocHighlighter;
lastDocHighlighter = null;
@@ -600,23 +598,23 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
}
}
- private TIntObjectHashMap<ArrayList<GutterMark>> myLineToGutterRenderers;
+ private TIntObjectHashMap<List<GutterMark>> myLineToGutterRenderers;
private void calcIconAreaWidth() {
- myLineToGutterRenderers = new TIntObjectHashMap<ArrayList<GutterMark>>();
+ myLineToGutterRenderers = new TIntObjectHashMap<List<GutterMark>>();
processRangeHighlighters(0, myEditor.getDocument().getTextLength(), new RangeHighlighterProcessor() {
@Override
public void process(RangeHighlighter highlighter) {
GutterMark renderer = highlighter.getGutterIconRenderer();
- if (renderer == null) return;
-
- int startOffset = highlighter.getStartOffset();
- int line = myEditor.getDocument().getLineNumber(startOffset);
+ if (renderer == null) {
+ return;
+ }
- ArrayList<GutterMark> renderers = myLineToGutterRenderers.get(line);
+ int line = myEditor.getDocument().getLineNumber(highlighter.getStartOffset());
+ List<GutterMark> renderers = myLineToGutterRenderers.get(line);
if (renderers == null) {
- renderers = new ArrayList<GutterMark>();
+ renderers = new SmartList<GutterMark>();
myLineToGutterRenderers.put(line, renderers);
}
@@ -628,9 +626,9 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
myIconsAreaWidth = START_ICON_AREA_WIDTH;
- myLineToGutterRenderers.forEachValue(new TObjectProcedure<ArrayList<GutterMark>>() {
+ myLineToGutterRenderers.forEachValue(new TObjectProcedure<List<GutterMark>>() {
@Override
- public boolean execute(ArrayList<GutterMark> renderers) {
+ public boolean execute(List<GutterMark> renderers) {
int width = 1;
for (int i = 0; i < renderers.size(); i++) {
GutterMark renderer = renderers.get(i);
@@ -677,7 +675,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
public boolean execute(int line) {
if (firstVisibleLine > line || lastVisibleLine < line) return true;
if (isLineCollapsed(line)) return true;
- ArrayList<GutterMark> renderers = myLineToGutterRenderers.get(line);
+ List<GutterMark> renderers = myLineToGutterRenderers.get(line);
paintIconRow(line, renderers, g);
return true;
}
@@ -690,7 +688,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
return region != null && region.getEndOffset() >= myEditor.getDocument().getLineEndOffset(line);
}
- private void paintIconRow(int line, ArrayList<GutterMark> row, final Graphics g) {
+ private void paintIconRow(int line, List<GutterMark> row, final Graphics g) {
processIconsRow(line, row, new LineGutterIconRendererProcessor() {
@Override
public void process(int x, int y, GutterMark renderer) {
@@ -743,7 +741,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
void process(int x, int y, GutterMark renderer);
}
- private void processIconsRow(int line, ArrayList<GutterMark> row, LineGutterIconRendererProcessor processor) {
+ private void processIconsRow(int line, List<GutterMark> row, LineGutterIconRendererProcessor processor) {
int middleCount = 0;
int middleSize = 0;
int x = getLineMarkerAreaOffset() + 1;
@@ -1119,7 +1117,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
if (toolTip != null && !toolTip.isEmpty()) {
final Ref<Point> t = new Ref<Point>(e.getPoint());
int line = EditorUtil.yPositionToLogicalLine(myEditor, e);
- ArrayList<GutterMark> row = myLineToGutterRenderers.get(line);
+ List<GutterMark> row = myLineToGutterRenderers.get(line);
Balloon.Position ballPosition = Balloon.Position.atRight;
if (row != null) {
final TreeMap<Integer, GutterMark> xPos = new TreeMap<Integer, GutterMark>();
@@ -1421,8 +1419,10 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
private GutterMark getGutterRenderer(final Point p) {
int line = convertPointToLineNumber(p);
if (line == -1) return null;
- ArrayList<GutterMark> renderers = myLineToGutterRenderers.get(line);
- if (renderers == null) return null;
+ List<GutterMark> renderers = myLineToGutterRenderers.get(line);
+ if (renderers == null) {
+ return null;
+ }
final GutterMark[] result = {null};
processIconsRow(line, renderers, new LineGutterIconRendererProcessor() {
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 aa04b488cf29..8b4192947be8 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
@@ -393,7 +393,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myFoldingModel.addListener(mySoftWrapModel, myCaretModel);
myIndentsModel = new IndentsModelImpl(this);
- myCaretModel.addCaretListener(new MultipleCaretListener() {
+ myCaretModel.addCaretListener(new CaretListener() {
@Nullable private LightweightHint myCurrentHint = null;
@Nullable private IndentGuideDescriptor myCurrentCaretGuide = null;
@@ -2289,6 +2289,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
position.x = drawSoftWrapAwareBackground(g, backColor, text, start, lEnd - lIterator.getSeparatorLength(), position, fontType,
defaultBackground, clip, softWrapsToSkip, caretRowPainted);
+ paintAfterLineEndBackgroundSegments(g, iterationState, position, defaultBackground, lineHeight);
+
if (lIterator.getLineNumber() < lastLineIndex) {
if (backColor != null && !backColor.equals(defaultBackground)) {
g.setColor(backColor);
@@ -2296,6 +2298,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
}
else {
+ if (iterationState.hasPastFileEndBackgroundSegments()) {
+ paintAfterLineEndBackgroundSegments(g, iterationState, position, defaultBackground, lineHeight);
+ }
paintAfterFileEndBackground(iterationState,
g,
position, clip,
@@ -2380,6 +2385,24 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
}
+ private void paintAfterLineEndBackgroundSegments(@NotNull Graphics g,
+ @NotNull IterationState iterationState,
+ @NotNull Point position,
+ @NotNull Color defaultBackground,
+ int lineHeight) {
+ while (iterationState.hasPastLineEndBackgroundSegment()) {
+ TextAttributes backgroundAttributes = iterationState.getPastLineEndBackgroundAttributes();
+ int width = EditorUtil.getSpaceWidth(backgroundAttributes.getFontType(), this) * iterationState.getPastLineEndBackgroundSegmentWidth();
+ Color color = getBackgroundColor(backgroundAttributes);
+ if (color != null && !color.equals(defaultBackground)) {
+ g.setColor(color);
+ g.fillRect(position.x, position.y, width, lineHeight);
+ }
+ position.x += width;
+ iterationState.advanceToNextPastLineEndBackgroundSegment();
+ }
+ }
+
private void paintRectangularSelection(@NotNull Graphics g) {
final SelectionModel model = getSelectionModel();
if (!model.hasBlockSelection()) return;
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 962230e8680e..8349aac12497 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
@@ -45,7 +45,6 @@ import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
import java.awt.*;
import java.util.Arrays;
import java.util.List;
@@ -201,7 +200,6 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList
}
private void runBatchFoldingOperation(final Runnable operation, final boolean dontCollapseCaret, final boolean moveCaret) {
- assert SwingUtilities.isEventDispatchThread() : Thread.currentThread();
assertIsDispatchThreadForEditor();
boolean oldDontCollapseCaret = myDoNotCollapseCaret;
myDoNotCollapseCaret |= dontCollapseCaret;
@@ -212,17 +210,20 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList
myIsBatchFoldingProcessing = true;
myFoldTree.myCachedLastIndex = -1;
- operation.run();
- myFoldTree.myCachedLastIndex = -1;
-
- if (!oldBatchFlag) {
- if (myFoldRegionsProcessed) {
- notifyBatchFoldingProcessingDone(moveCaret);
- myFoldRegionsProcessed = false;
+ try {
+ operation.run();
+ } finally {
+ myFoldTree.myCachedLastIndex = -1;
+
+ if (!oldBatchFlag) {
+ if (myFoldRegionsProcessed) {
+ notifyBatchFoldingProcessingDone(moveCaret);
+ myFoldRegionsProcessed = false;
+ }
+ myIsBatchFoldingProcessing = false;
}
- myIsBatchFoldingProcessing = false;
+ myDoNotCollapseCaret = oldDontCollapseCaret;
}
- myDoNotCollapseCaret = oldDontCollapseCaret;
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/IterationState.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/IterationState.java
index 3f3ed7e054a1..4bd96fdda625 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/IterationState.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/IterationState.java
@@ -17,13 +17,17 @@ package com.intellij.openapi.editor.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.ex.*;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
-import com.intellij.openapi.editor.markup.*;
+import com.intellij.openapi.editor.markup.EffectType;
+import com.intellij.openapi.editor.markup.HighlighterLayer;
+import com.intellij.openapi.editor.markup.HighlighterTargetArea;
+import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.Comparing;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.containers.ContainerUtil;
@@ -89,7 +93,13 @@ public final class IterationState {
private final int[] mySelectionStarts;
private final int[] mySelectionEnds;
+ private final int[] myVirtualSelectionStarts;
+ private final int[] myVirtualSelectionEnds;
private int myCurrentSelectionIndex = 0;
+ private int myCurrentVirtualSelectionIndex = 0;
+ private boolean myCurrentLineHasVirtualSelection;
+ private int myCurrentPastLineEndBackgroundSegment; // 0 - before selection, 1 - in selection, 2 - after selection
+ private Color myCurrentBackgroundColor;
private final List<RangeHighlighterEx> myCurrentHighlighters = new ArrayList<RangeHighlighterEx>();
@@ -123,8 +133,32 @@ public final class IterationState {
myHighlighterIterator = editor.getHighlighter().createIterator(start);
boolean hasSelection = useCaretAndSelection && (editor.getCaretModel().supportsMultipleCarets() || editor.getSelectionModel().hasSelection() || editor.getSelectionModel().hasBlockSelection());
- mySelectionStarts = hasSelection ? editor.getSelectionModel().getBlockSelectionStarts() : ArrayUtilRt.EMPTY_INT_ARRAY;
- mySelectionEnds = hasSelection ? editor.getSelectionModel().getBlockSelectionEnds() : ArrayUtilRt.EMPTY_INT_ARRAY;
+ if (!hasSelection) {
+ mySelectionStarts = ArrayUtilRt.EMPTY_INT_ARRAY;
+ mySelectionEnds = ArrayUtilRt.EMPTY_INT_ARRAY;
+ myVirtualSelectionStarts = ArrayUtilRt.EMPTY_INT_ARRAY;
+ myVirtualSelectionEnds = ArrayUtilRt.EMPTY_INT_ARRAY;
+ }
+ else if (editor.getCaretModel().supportsMultipleCarets()) {
+ List<Caret> carets = editor.getCaretModel().getAllCarets();
+ mySelectionStarts = new int[carets.size()];
+ mySelectionEnds = new int[carets.size()];
+ myVirtualSelectionStarts = new int[carets.size()];
+ myVirtualSelectionEnds = new int[carets.size()];
+ for (int i = 0; i < carets.size(); i++) {
+ Caret caret = carets.get(i);
+ mySelectionStarts[i] = caret.getSelectionStart();
+ mySelectionEnds[i] = caret.getSelectionEnd();
+ myVirtualSelectionStarts[i] = caret.getSelectionStartPosition().column - editor.offsetToVisualPosition(mySelectionStarts[i]).column;
+ myVirtualSelectionEnds[i] = caret.getSelectionEndPosition().column - editor.offsetToVisualPosition(mySelectionEnds[i]).column;
+ }
+ }
+ else {
+ mySelectionStarts = editor.getSelectionModel().getBlockSelectionStarts();
+ mySelectionEnds = editor.getSelectionModel().getBlockSelectionEnds();
+ myVirtualSelectionStarts = new int[mySelectionStarts.length];
+ myVirtualSelectionEnds = new int[mySelectionEnds.length];
+ }
myFoldingModel = editor.getFoldingModel();
myFoldTextAttributes = myFoldingModel.getPlaceholderAttributes();
@@ -140,7 +174,7 @@ public final class IterationState {
myCaretRowStart = caretModel.getVisualLineStart();
myCaretRowEnd = caretModel.getVisualLineEnd();
- MarkupModelEx editorMarkup = (MarkupModelEx)editor.getMarkupModel();
+ MarkupModelEx editorMarkup = editor.getMarkupModel();
myView = new HighlighterSweep(editorMarkup, start, myEnd);
final MarkupModelEx docMarkup = (MarkupModelEx)DocumentMarkupModel.forDocument(editor.getDocument(), editor.getProject(), true);
@@ -181,31 +215,20 @@ public final class IterationState {
private void advance() {
if (myNextHighlighter != null) {
- if (myNextHighlighter.getAffectedAreaStartOffset() <= myStartOffset) {
- myCurrentHighlighters.add(myNextHighlighter);
- myNextHighlighter = null;
- }
-
- // There is a possible case that there are two highlighters mapped to offset of the first non-white space symbol
- // on a line. The second one may have HighlighterTargetArea.LINES_IN_RANGE area, so, we should use it for indent
- // background processing (that is the case for the active debugger line that starts with highlighted brace/bracket).
- // So, we check if it's worth to use next highlighter here.
- else if (myIterator.hasNext()) {
- final RangeHighlighterEx lookAhead = myIterator.next();
- if (lookAhead.getAffectedAreaStartOffset() <= myStartOffset) {
- myCurrentHighlighters.add(lookAhead);
- }
- else {
- myIterator.pushBack(lookAhead);
- }
+ if (myNextHighlighter.getAffectedAreaStartOffset() > myStartOffset) {
+ return;
}
+
+ myCurrentHighlighters.add(myNextHighlighter);
+ myNextHighlighter = null;
}
- while (myNextHighlighter == null && myIterator.hasNext()) {
+ while (myIterator.hasNext()) {
RangeHighlighterEx highlighter = myIterator.next();
if (!skipHighlighter(highlighter)) {
if (highlighter.getAffectedAreaStartOffset() > myStartOffset) {
myNextHighlighter = highlighter;
+ break;
}
else {
myCurrentHighlighters.add(highlighter);
@@ -237,6 +260,7 @@ public final class IterationState {
myStartOffset = myEndOffset;
advanceSegmentHighlighters();
advanceCurrentSelectionIndex();
+ advanceCurrentVirtualSelectionIndex();
myCurrentFold = myFoldingModel.fetchOutermost(myStartOffset);
if (myCurrentFold != null) {
@@ -298,6 +322,13 @@ public final class IterationState {
}
}
+ private void advanceCurrentVirtualSelectionIndex() {
+ while (myCurrentVirtualSelectionIndex < mySelectionEnds.length
+ && (myStartOffset > mySelectionEnds[myCurrentVirtualSelectionIndex] || myVirtualSelectionEnds[myCurrentVirtualSelectionIndex] <= 0)) {
+ myCurrentVirtualSelectionIndex++;
+ }
+ }
+
private int getSelectionEnd() {
if (myCurrentSelectionIndex >= mySelectionStarts.length) {
return myEnd;
@@ -402,12 +433,17 @@ public final class IterationState {
List<TextAttributes> cachedAttributes = myCachedAttributesList;
cachedAttributes.clear();
+ int selectionAttributesIndex = -1; // a 'would-be' or real position of selection attributes in attributes list
+
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < size; i++) {
RangeHighlighterEx highlighter = myCurrentHighlighters.get(i);
- if (selection != null && highlighter.getLayer() < HighlighterLayer.SELECTION) {
- cachedAttributes.add(selection);
- selection = null;
+ if (highlighter.getLayer() < HighlighterLayer.SELECTION) {
+ selectionAttributesIndex = cachedAttributes.size();
+ if (selection != null) {
+ cachedAttributes.add(selection);
+ selection = null;
+ }
}
if (syntax != null && highlighter.getLayer() < HighlighterLayer.SYNTAX) {
@@ -436,6 +472,9 @@ public final class IterationState {
}
}
+ if (selectionAttributesIndex < 0) {
+ selectionAttributesIndex = cachedAttributes.size();
+ }
if (selection != null) cachedAttributes.add(selection);
if (fold != null) cachedAttributes.add(fold);
if (guard != null) cachedAttributes.add(guard);
@@ -448,6 +487,8 @@ public final class IterationState {
EffectType effectType = null;
int fontType = 0;
+ boolean selectionBackgroundIsPotentiallyVisible = cachedAttributes.isEmpty();
+
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < cachedAttributes.size(); i++) {
TextAttributes attrs = cachedAttributes.get(i);
@@ -457,6 +498,9 @@ public final class IterationState {
}
if (back == null) {
+ if (isInSelection && i == selectionAttributesIndex || !isInSelection && i >= selectionAttributesIndex) {
+ selectionBackgroundIsPotentiallyVisible = true;
+ }
back = ifDiffers(attrs.getBackgroundColor(), myDefaultBackground);
}
@@ -475,6 +519,16 @@ public final class IterationState {
if (effectType == null) effectType = EffectType.BOXED;
myMergedAttributes.setAttributes(fore, back, effect, null, effectType, fontType);
+
+ myCurrentBackgroundColor = back;
+ if (selectionBackgroundIsPotentiallyVisible && myCurrentVirtualSelectionIndex < mySelectionStarts.length && myStartOffset == mySelectionEnds[myCurrentVirtualSelectionIndex]) {
+ myCurrentLineHasVirtualSelection = true;
+ myCurrentPastLineEndBackgroundSegment = myVirtualSelectionStarts[myCurrentVirtualSelectionIndex] > 0 ? 0 : 1;
+ }
+ else {
+ myCurrentLineHasVirtualSelection = false;
+ myCurrentPastLineEndBackgroundSegment = 0;
+ }
}
@Nullable
@@ -504,6 +558,41 @@ public final class IterationState {
return myCurrentFold;
}
+ public boolean hasPastLineEndBackgroundSegment() {
+ return myCurrentLineHasVirtualSelection && myCurrentPastLineEndBackgroundSegment < 2;
+ }
+
+ public int getPastLineEndBackgroundSegmentWidth() {
+ switch (myCurrentPastLineEndBackgroundSegment) {
+ case 0: return myVirtualSelectionStarts[myCurrentVirtualSelectionIndex];
+ case 1: return myVirtualSelectionEnds[myCurrentVirtualSelectionIndex] - myVirtualSelectionStarts[myCurrentVirtualSelectionIndex];
+ default: return 0;
+ }
+ }
+
+ @NotNull
+ public TextAttributes getPastLineEndBackgroundAttributes() {
+ myMergedAttributes.setBackgroundColor(myCurrentPastLineEndBackgroundSegment == 1 ? mySelectionAttributes.getBackgroundColor() : myCurrentBackgroundColor);
+ return myMergedAttributes;
+ }
+
+ public void advanceToNextPastLineEndBackgroundSegment() {
+ myCurrentPastLineEndBackgroundSegment++;
+ }
+
+ public boolean hasPastFileEndBackgroundSegments() {
+ myCurrentLineHasVirtualSelection = myVirtualSelectionEnds.length > 0
+ && myVirtualSelectionEnds[myVirtualSelectionEnds.length - 1] > 0
+ && myEndOffset == myEnd
+ && mySelectionEnds[mySelectionStarts.length - 1] == myEndOffset;
+ if (myCurrentLineHasVirtualSelection) {
+ myCurrentVirtualSelectionIndex = myVirtualSelectionStarts.length - 1;
+ myCurrentPastLineEndBackgroundSegment = myVirtualSelectionStarts[myCurrentVirtualSelectionIndex] > 0 ? 0 : 1;
+ myCurrentBackgroundColor = myEndOffset >= myCaretRowStart ? myCaretRowAttributes.getBackgroundColor() : myDefaultBackground;
+ }
+ return myCurrentLineHasVirtualSelection;
+ }
+
@Nullable
public Color getPastFileEndBackground() {
boolean isInCaretRow = myEditor.getCaretModel().getLogicalPosition().line >= myDocument.getLineCount() - 1;
@@ -543,8 +632,8 @@ public final class IterationState {
return layerDiff;
}
// prefer more specific region
- int o1Length = o1.getEndOffset() - o1.getStartOffset();
- int o2Length = o2.getEndOffset() - o2.getStartOffset();
+ int o1Length = o1.getAffectedAreaEndOffset() - o1.getAffectedAreaStartOffset();
+ int o2Length = o2.getAffectedAreaEndOffset() - o2.getAffectedAreaStartOffset();
return o1Length - o2Length;
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java
index 46be8b85a5cf..7ee0e4d2668d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java
@@ -38,7 +38,6 @@ import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
@@ -47,7 +46,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.datatransfer.StringSelection;
-import java.util.*;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentListener {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.SelectionModelImpl");
@@ -214,42 +216,40 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
int endLine = Math.max(Math.min(blockEnd.line, myEditor.getDocument().getLineCount() - 1), 0);
int step = endLine < startLine ? -1 : 1;
int count = 1 + Math.abs(endLine - startLine);
- List<LogicalPosition> positions = new LinkedList<LogicalPosition>();
- List<TextRange> selections = new LinkedList<TextRange>();
+ List<CaretState> caretStates = new LinkedList<CaretState>();
boolean hasSelection = false;
for (int line = startLine, i = 0; i < count; i++, line += step) {
int startColumn = blockStart.column;
int endColumn = blockEnd.column;
int lineEndOffset = myEditor.getDocument().getLineEndOffset(line);
- int lineWidth = myEditor.offsetToLogicalPosition(lineEndOffset).column;
- if (startColumn > lineWidth && endColumn > lineWidth) {
+ LogicalPosition lineEndPosition = myEditor.offsetToLogicalPosition(lineEndOffset);
+ int lineWidth = lineEndPosition.column;
+ if (startColumn > lineWidth && endColumn > lineWidth && !myEditor.isColumnMode()) {
LogicalPosition caretPos = new LogicalPosition(line, Math.min(startColumn, endColumn));
- positions.add(caretPos);
- selections.add(new TextRange(lineEndOffset, lineEndOffset));
+ caretStates.add(new CaretState(caretPos,
+ lineEndPosition,
+ lineEndPosition));
}
else {
- LogicalPosition startPos = new LogicalPosition(line, Math.min(startColumn, lineWidth));
- LogicalPosition endPos = new LogicalPosition(line, Math.min(endColumn, lineWidth));
+ LogicalPosition startPos = new LogicalPosition(line, myEditor.isColumnMode() ? startColumn : Math.min(startColumn, lineWidth));
+ LogicalPosition endPos = new LogicalPosition(line, myEditor.isColumnMode() ? endColumn : Math.min(endColumn, lineWidth));
int startOffset = myEditor.logicalPositionToOffset(startPos);
int endOffset = myEditor.logicalPositionToOffset(endPos);
- positions.add(endPos);
- selections.add(new TextRange(Math.min(startOffset, endOffset), Math.max(startOffset, endOffset)));
+ caretStates.add(new CaretState(endPos, startPos, endPos));
hasSelection |= startOffset != endOffset;
}
}
if (hasSelection && !myEditor.isColumnMode()) { // filtering out lines without selection
- Iterator<LogicalPosition> positionIterator = positions.iterator();
- Iterator<TextRange> selectionIterator = selections.iterator();
- while(selectionIterator.hasNext()) {
- TextRange selection = selectionIterator.next();
- positionIterator.next();
- if (selection.isEmpty()) {
- selectionIterator.remove();
- positionIterator.remove();
+ Iterator<CaretState> caretStateIterator = caretStates.iterator();
+ while(caretStateIterator.hasNext()) {
+ CaretState state = caretStateIterator.next();
+ //noinspection ConstantConditions
+ if (state.getSelectionStart().equals(state.getSelectionEnd())) {
+ caretStateIterator.remove();
}
}
}
- myEditor.getCaretModel().setCaretsAndSelections(positions, selections);
+ myEditor.getCaretModel().setCaretsAndSelections(caretStates);
}
else {
removeSelection();
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 607e182dd3cb..ef86c6f3ae3d 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
@@ -18,7 +18,6 @@ package com.intellij.openapi.editor.textarea;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.editor.markup.TextAttributes;
-import com.intellij.openapi.util.Segment;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -151,6 +150,11 @@ public class TextComponentCaretModel implements CaretModel {
return myCaret;
}
+ @Override
+ public int getCaretCount() {
+ return 1;
+ }
+
@NotNull
@Override
public List<Caret> getAllCarets() {
@@ -179,7 +183,7 @@ public class TextComponentCaretModel implements CaretModel {
}
@Override
- public void setCaretsAndSelections(@NotNull List<LogicalPosition> caretPositions, @NotNull List<? extends Segment> selections) {
+ public void setCaretsAndSelections(@NotNull List<CaretState> caretStates) {
throw new UnsupportedOperationException("Multiple carets are not supported");
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java
index 978c26068655..32169662ba2a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java
@@ -41,6 +41,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
@@ -141,7 +142,7 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme
}
LOG.assertTrue(selectedEditor != null);
final int selectedProviderIndex = ArrayUtilRt.find(editors, selectedEditor);
- LOG.assertTrue(selectedProviderIndex != -1);
+ LOG.assertTrue(selectedProviderIndex != -1, "Can't find " + selectedEditor + " among " + Arrays.asList(editors));
final HistoryEntry entry = getEntry(file);
if(entry != null){
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
index 14af91d690f1..54803815c898 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
@@ -37,6 +37,7 @@ import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
+import com.intellij.openapi.editor.impl.EditorFactoryImpl;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl;
@@ -184,7 +185,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
document = (DocumentEx)getCachedDocument(file);
if (document != null) return document; // Double checking
- document = (DocumentEx)createDocument(text);
+ document = (DocumentEx)createDocument(text, file);
document.setModificationStamp(file.getModificationStamp());
final FileType fileType = file.getFileType();
document.setReadOnly(!file.isWritable() || fileType.isBinary());
@@ -229,8 +230,9 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
return false;
}
- private static Document createDocument(final CharSequence text) {
- return EditorFactory.getInstance().createDocument(text);
+ private static Document createDocument(final CharSequence text, VirtualFile file) {
+ boolean acceptSlashR = file instanceof LightVirtualFile && StringUtil.indexOf(text, '\r') >= 0;
+ return ((EditorFactoryImpl)EditorFactory.getInstance()).createDocument(text, acceptSlashR, false);
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java
index 6e80c6da70fa..752ab1228c3e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java
@@ -119,7 +119,7 @@ public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements Projec
};
eventMulticaster.addDocumentListener(documentListener, myProject);
- CaretListener caretListener = new CaretListener() {
+ CaretListener caretListener = new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
onCaretPositionChanged(e);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java
index 1ffd02740387..d7b881a0cba4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java
@@ -50,6 +50,7 @@ import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.StatusBarEx;
import com.intellij.ui.components.JBLoadingPanel;
import com.intellij.util.EditorPopupHandler;
+import com.intellij.util.FileContentUtilCore;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -348,7 +349,9 @@ class TextEditorComponent extends JBLoadingPanel implements DataProvider {
// File can be invalidated after file changes name (extension also
// can changes). The editor should be removed if it's invalid.
updateValidProperty();
- if (Comparing.equal(e.getFile(), myFile) && !Comparing.equal(e.getOldValue(), e.getNewValue())) {
+ if (Comparing.equal(e.getFile(), myFile) &&
+ (FileContentUtilCore.FORCE_RELOAD_REQUESTOR.equals(e.getRequestor()) ||
+ !Comparing.equal(e.getOldValue(), e.getNewValue()))) {
updateHighlighters();
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java
index 4514ee8fbe58..47c0088fa2ce 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java
@@ -57,8 +57,10 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
@NonNls private static final String TYPE_ID = "text-editor";
@NonNls private static final String LINE_ATTR = "line";
@NonNls private static final String COLUMN_ATTR = "column";
- @NonNls private static final String SELECTION_START_ATTR = "selection-start";
- @NonNls private static final String SELECTION_END_ATTR = "selection-end";
+ @NonNls private static final String SELECTION_START_LINE_ATTR = "selection-start-line";
+ @NonNls private static final String SELECTION_START_COLUMN_ATTR = "selection-start-column";
+ @NonNls private static final String SELECTION_END_LINE_ATTR = "selection-end-line";
+ @NonNls private static final String SELECTION_END_COLUMN_ATTR = "selection-end-column";
@NonNls private static final String VERTICAL_SCROLL_PROPORTION_ATTR = "vertical-scroll-proportion";
@NonNls private static final String VERTICAL_OFFSET_ATTR = "vertical-offset";
@NonNls private static final String MAX_VERTICAL_OFFSET_ATTR = "max-vertical-offset";
@@ -100,10 +102,10 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
try {
List<Element> caretElements = element.getChildren(CARET_ELEMENT);
- if (caretElements.isEmpty()) { // legacy format
+ if (caretElements.isEmpty()) {
state.CARETS = new TextEditorState.CaretState[] {readCaretInfo(element)};
}
- else { // new format
+ else {
state.CARETS = new TextEditorState.CaretState[caretElements.size()];
for (int i = 0; i < caretElements.size(); i++) {
state.CARETS[i] = readCaretInfo(caretElements.get(i));
@@ -129,8 +131,10 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
TextEditorState.CaretState caretState = new TextEditorState.CaretState();
caretState.LINE = parseWithDefault(element, LINE_ATTR);
caretState.COLUMN = parseWithDefault(element, COLUMN_ATTR);
- caretState.SELECTION_START = parseWithDefault(element, SELECTION_START_ATTR);
- caretState.SELECTION_END = parseWithDefault(element, SELECTION_END_ATTR);
+ caretState.SELECTION_START_LINE = parseWithDefault(element, SELECTION_START_LINE_ATTR);
+ caretState.SELECTION_START_COLUMN = parseWithDefault(element, SELECTION_START_COLUMN_ATTR);
+ caretState.SELECTION_END_LINE = parseWithDefault(element, SELECTION_END_LINE_ATTR);
+ caretState.SELECTION_END_COLUMN = parseWithDefault(element, SELECTION_END_COLUMN_ATTR);
return caretState;
}
@@ -151,8 +155,10 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
Element e = new Element(CARET_ELEMENT);
e.setAttribute(LINE_ATTR, Integer.toString(caretState.LINE));
e.setAttribute(COLUMN_ATTR, Integer.toString(caretState.COLUMN));
- e.setAttribute(SELECTION_START_ATTR, Integer.toString(caretState.SELECTION_START));
- e.setAttribute(SELECTION_END_ATTR, Integer.toString(caretState.SELECTION_END));
+ e.setAttribute(SELECTION_START_LINE_ATTR, Integer.toString(caretState.SELECTION_START_LINE));
+ e.setAttribute(SELECTION_START_COLUMN_ATTR, Integer.toString(caretState.SELECTION_START_COLUMN));
+ e.setAttribute(SELECTION_END_LINE_ATTR, Integer.toString(caretState.SELECTION_END_LINE));
+ e.setAttribute(SELECTION_END_COLUMN_ATTR, Integer.toString(caretState.SELECTION_END_COLUMN));
element.addContent(e);
}
}
@@ -227,8 +233,12 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
state.CARETS[i] = new TextEditorState.CaretState();
state.CARETS[i].LINE = caret.getLogicalPosition().line;
state.CARETS[i].COLUMN = caret.getLogicalPosition().column;
- state.CARETS[i].SELECTION_START = caret.getSelectionStart();
- state.CARETS[i++].SELECTION_END = caret.getSelectionEnd();
+ LogicalPosition selectionStartPosition = editor.visualToLogicalPosition(caret.getSelectionStartPosition());
+ LogicalPosition selectionEndPosition = editor.visualToLogicalPosition(caret.getSelectionEndPosition());
+ state.CARETS[i].SELECTION_START_LINE = selectionStartPosition.line;
+ state.CARETS[i].SELECTION_START_COLUMN = selectionStartPosition.column;
+ state.CARETS[i].SELECTION_END_LINE = selectionEndPosition.line;
+ state.CARETS[i++].SELECTION_END_COLUMN = selectionEndPosition.column;
}
// Saving scrolling proportion on UNDO may cause undesirable results of undo action fails to perform since
@@ -246,13 +256,13 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
protected void setStateImpl(final Project project, final Editor editor, final TextEditorState state){
if (editor.getCaretModel().supportsMultipleCarets()) {
CaretModel caretModel = editor.getCaretModel();
- ArrayList<LogicalPosition> positions = new ArrayList<LogicalPosition>();
- ArrayList<Segment> selections = new ArrayList<Segment>();
+ List<CaretState> states = new ArrayList<CaretState>(state.CARETS.length);
for (TextEditorState.CaretState caretState : state.CARETS) {
- positions.add(new LogicalPosition(caretState.LINE, caretState.COLUMN));
- selections.add(new TextRange(caretState.SELECTION_START, caretState.SELECTION_END));
+ states.add(new CaretState(new LogicalPosition(caretState.LINE, caretState.COLUMN),
+ new LogicalPosition(caretState.SELECTION_START_LINE, caretState.SELECTION_START_COLUMN),
+ new LogicalPosition(caretState.SELECTION_END_LINE, caretState.SELECTION_END_COLUMN)));
}
- caretModel.setCaretsAndSelections(positions, selections);
+ caretModel.setCaretsAndSelections(states);
} else {
LogicalPosition pos = new LogicalPosition(state.CARETS[0].LINE, state.CARETS[0].COLUMN);
editor.getCaretModel().moveToLogicalPosition(pos);
@@ -275,15 +285,14 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
}
}
- final Document document = editor.getDocument();
-
if (!editor.getCaretModel().supportsMultipleCarets()) {
- if (state.CARETS[0].SELECTION_START == state.CARETS[0].SELECTION_END) {
+ if (state.CARETS[0].SELECTION_START_LINE == state.CARETS[0].SELECTION_END_LINE
+ && state.CARETS[0].SELECTION_START_COLUMN == state.CARETS[0].SELECTION_END_COLUMN) {
editor.getSelectionModel().removeSelection();
}
else {
- int startOffset = Math.min(state.CARETS[0].SELECTION_START, document.getTextLength());
- int endOffset = Math.min(state.CARETS[0].SELECTION_END, document.getTextLength());
+ int startOffset = editor.logicalPositionToOffset(new LogicalPosition(state.CARETS[0].SELECTION_START_LINE, state.CARETS[0].SELECTION_START_COLUMN));
+ int endOffset = editor.logicalPositionToOffset(new LogicalPosition(state.CARETS[0].SELECTION_END_LINE, state.CARETS[0].SELECTION_END_COLUMN));
editor.getSelectionModel().setSelection(startOffset, endOffset);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorState.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorState.java
index 3319d511e1a1..d4aca486c041 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorState.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorState.java
@@ -122,8 +122,10 @@ public final class TextEditorState implements FileEditorState {
public static class CaretState {
public int LINE;
public int COLUMN;
- public int SELECTION_START;
- public int SELECTION_END;
+ public int SELECTION_START_LINE;
+ public int SELECTION_START_COLUMN;
+ public int SELECTION_END_LINE;
+ public int SELECTION_END_COLUMN;
public boolean equals(Object o) {
if (!(o instanceof CaretState)) {
@@ -134,8 +136,10 @@ public final class TextEditorState implements FileEditorState {
if (COLUMN != caretState.COLUMN) return false;
if (LINE != caretState.LINE) return false;
- if (SELECTION_START != caretState.SELECTION_START) return false;
- if (SELECTION_END != caretState.SELECTION_END) return false;
+ if (SELECTION_START_LINE != caretState.SELECTION_START_LINE) return false;
+ if (SELECTION_START_COLUMN != caretState.SELECTION_START_COLUMN) return false;
+ if (SELECTION_END_LINE != caretState.SELECTION_END_LINE) return false;
+ if (SELECTION_END_COLUMN != caretState.SELECTION_END_COLUMN) return false;
return true;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java
index 77e55ea28d26..817cdaa5e458 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java
@@ -651,8 +651,8 @@ public final class IdeKeyEventDispatcher implements Disposable {
if (!(component instanceof JComponent)) {
continue;
}
- ArrayList listOfActions = (ArrayList)((JComponent)component).getClientProperty(AnAction.ourClientProperty);
- if (listOfActions == null) {
+ List<AnAction> listOfActions = ActionUtil.getActions((JComponent)component);
+ if (listOfActions.isEmpty()) {
continue;
}
for (Object listOfAction : listOfActions) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java
index b8095397e016..94f72f6da840 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java
@@ -19,6 +19,7 @@ import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
+import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.actionSystem.impl.PresentationFactory;
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.KeymapManager;
@@ -78,21 +79,16 @@ public final class IdeMouseEventDispatcher {
// here we try to find "local" shortcuts
if (component instanceof JComponent) {
- @SuppressWarnings("unchecked")
- final ArrayList<AnAction> listOfActions = (ArrayList<AnAction>)((JComponent)component).getClientProperty(AnAction.ourClientProperty);
- if (listOfActions != null) {
- for (AnAction action : listOfActions) {
- final Shortcut[] shortcuts = action.getShortcutSet().getShortcuts();
- for (Shortcut shortcut : shortcuts) {
- if (mouseShortcut.equals(shortcut) && !myActions.contains(action)) {
- myActions.add(action);
- }
+ for (AnAction action : ActionUtil.getActions((JComponent)component)) {
+ for (Shortcut shortcut : action.getShortcutSet().getShortcuts()) {
+ if (mouseShortcut.equals(shortcut) && !myActions.contains(action)) {
+ myActions.add(action);
}
}
- // once we've found a proper local shortcut(s), we exit
- if (! myActions.isEmpty()) {
- return;
- }
+ }
+ // once we've found a proper local shortcut(s), we exit
+ if (!myActions.isEmpty()) {
+ return;
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java
index 5751e4a1d28b..ada78025bd3e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/DefaultProject.java
@@ -15,8 +15,6 @@
*/
package com.intellij.openapi.project.impl;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.ProjectManager;
import org.jetbrains.annotations.NotNull;
@@ -34,13 +32,4 @@ public class DefaultProject extends ProjectImpl {
public boolean isDefault() {
return true;
}
-
- @Override
- public synchronized void dispose() {
- if (!ApplicationManager.getApplication().isDisposeInProgress() && !ApplicationManager.getApplication().isUnitTestMode()) {
- Logger.getInstance(DefaultProject.class).error(new Exception("Too young to die"));
- }
-
- super.dispose();
- }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
index 35586cf8c8d6..90cbffe3d96b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
@@ -263,7 +263,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
private void initProject(@NotNull ProjectImpl project, @Nullable ProjectImpl template) throws IOException {
final ProgressIndicator indicator = myProgressManager.getProgressIndicator();
- if (indicator != null) {
+ if (indicator != null && !project.isDefault()) {
indicator.setText(ProjectBundle.message("loading.components.for", project.getName()));
indicator.setIndeterminate(true);
}
@@ -299,6 +299,10 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
}
private static void scheduleDispose(final ProjectImpl project) {
+ if (project.isDefault()) {
+ return;
+ }
+
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java
index aa7b6b3874e7..d54bfcc304b4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java
@@ -251,6 +251,7 @@ public class PluginsAdvertiser implements StartupActivity {
if (project.isDisposed()) return;
if (extensions == null) {
loadSupportedExtensions(myAllPlugins);
+ if (project.isDisposed()) return;
EditorNotifications.getInstance(project).updateAllNotifications();
}
final Map<String, Plugin> ids = new HashMap<String, Plugin>();
@@ -280,7 +281,9 @@ public class PluginsAdvertiser implements StartupActivity {
for (IdeaPluginDescriptor loadedPlugin : myAllPlugins) {
final PluginId pluginId = loadedPlugin.getPluginId();
- if (ids.containsKey(pluginId.getIdString()) && !disabledPlugins.contains(pluginId.getIdString())) {
+ if (ids.containsKey(pluginId.getIdString()) &&
+ !disabledPlugins.contains(pluginId.getIdString()) &&
+ !PluginManagerCore.isBrokenPlugin(loadedPlugin)) {
myPlugins.add(PluginDownloader.createDownloader(loadedPlugin));
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/VirtualFileImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/VirtualFileImpl.java
index 3c1922e29ec8..be96d70a9db3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/VirtualFileImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/VirtualFileImpl.java
@@ -1,6 +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.
@@ -45,6 +44,7 @@ abstract class VirtualFileImpl extends VirtualFile implements VirtualFileWithId
return myFileSystem;
}
+ @NotNull
@Override
public String getPath() {
if (myParent == null) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java
index 110d71003867..873ac0200b16 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java
@@ -102,6 +102,7 @@ class VirtualFileImpl extends HttpVirtualFile {
return myFileSystem;
}
+ @NotNull
@Override
public String getPath() {
return myPath;
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java
index 7f0b5e8a4e9d..e12d756d901e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.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.
@@ -260,14 +260,14 @@ public class JarHandler extends JarHandlerBase {
private final byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer();
@Override
- public void save(DataOutput out, CacheLibraryInfo value) throws IOException {
+ public void save(@NotNull DataOutput out, CacheLibraryInfo value) throws IOException {
IOUtil.writeUTFFast(myBuffer, out, value.mySnapshotPath);
out.writeLong(value.myModificationTime);
out.writeLong(value.myFileLength);
}
@Override
- public CacheLibraryInfo read(DataInput in) throws IOException {
+ public CacheLibraryInfo read(@NotNull DataInput in) throws IOException {
return new CacheLibraryInfo(IOUtil.readUTFFast(myBuffer, in), in.readLong(), in.readLong());
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FakeVirtualFile.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FakeVirtualFile.java
index 24861243f093..5dc589fa7b66 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FakeVirtualFile.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FakeVirtualFile.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.
@@ -38,6 +38,7 @@ public class FakeVirtualFile extends StubVirtualFile {
return myParent;
}
+ @NotNull
@Override
public String getPath() {
final String basePath = myParent.getPath();
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 ab9655a75c03..3f2c4abebf7f 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
@@ -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.
@@ -42,12 +42,12 @@ public class FileNameCache {
public static int storeName(@NotNull String name) {
final int idx = FSRecords.getNameId(name);
- cacheData(name, idx);
+ cacheData(name, idx, calcStripeIdFromNameId(idx));
return idx;
}
@NotNull
- private static IntObjectLinkedMap.MapEntry<Object> cacheData(String name, int id) {
+ private static IntObjectLinkedMap.MapEntry<Object> cacheData(String name, int id, int stripe) {
if (name == null) {
ourNames.markCorrupted();
throw new RuntimeException("VFS name enumerator corrupted");
@@ -55,7 +55,6 @@ public class FileNameCache {
Object rawName = convertToBytesIfAsciiString(name);
IntObjectLinkedMap.MapEntry<Object> entry = new IntObjectLinkedMap.MapEntry<Object>(id, rawName);
- final int stripe = calcStripeIdFromNameId(id);
synchronized (ourNameCache[stripe]) {
return ourNameCache[stripe].cacheEntry(entry);
}
@@ -99,7 +98,7 @@ public class FileNameCache {
}
}
- return cacheData(FSRecords.getNameByNameId(id), id);
+ return cacheData(FSRecords.getNameByNameId(id), id, stripe);
}
@NotNull
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 33c024fc5cfe..94f73699ef99 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
@@ -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,6 +24,7 @@ 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 org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -124,4 +125,19 @@ public class VirtualFileImpl extends VirtualFileSystemEntry {
public OutputStream getOutputStream(final Object requestor, final long modStamp, final long timeStamp) throws IOException {
return VfsUtilCore.outputStreamAddingBOM(ourPersistence.getOutputStream(this, requestor, modStamp, timeStamp), this);
}
+
+ @Override
+ public String getDetectedLineSeparator() {
+ if (getFlagInt(SYSTEM_LINE_SEPARATOR_DETECTED)) {
+ return LineSeparator.getSystemLineSeparator().getSeparatorString();
+ }
+ return super.getDetectedLineSeparator();
+ }
+
+ @Override
+ public void setDetectedLineSeparator(String separator) {
+ boolean hasSystemSeparator = LineSeparator.getSystemLineSeparator().getSeparatorString().equals(separator);
+ setFlagInt(SYSTEM_LINE_SEPARATOR_DETECTED, hasSystemSeparator);
+ super.setDetectedLineSeparator(hasSystemSeparator ? null : separator);
+ }
}
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 2d5b5195dad6..e0772bc3e4fc 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
@@ -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,14 +52,15 @@ 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;
+ 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;
private static final int HAS_SYMLINK_FLAG = 0x40000000;
private static final int IS_SPECIAL_FLAG = 0x80000000;
- private static final int IS_WRITABLE_FLAG = 0x01000000;
- private static final int IS_HIDDEN_FLAG = 0x02000000;
- private static final int INDEXED_FLAG = 0x04000000;
- static final int CHILDREN_CACHED = 0x08000000;
+ static final int SYSTEM_LINE_SEPARATOR_DETECTED = CHILDREN_CACHED; // makes sense only for non-directory file
private 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;
@@ -68,6 +69,10 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
private volatile VirtualDirectoryImpl myParent;
private volatile int myFlags;
private volatile int myId;
+
+ static {
+ assert (~ALL_FLAGS_MASK) == LocalTimeCounter.TIME_MASK;
+ }
public VirtualFileSystemEntry(int nameId, VirtualDirectoryImpl parent, int id, @PersistentFS.Attributes int attributes) {
myParent = parent;
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java
index c1c7cd6371fb..de9a6d51b498 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.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.
@@ -543,12 +543,12 @@ public class FSRecords implements Forceable {
private static class ContentHashesDescriptor implements KeyDescriptor<byte[]>, DifferentSerializableBytesImplyNonEqualityPolicy {
@Override
- public void save(DataOutput out, byte[] value) throws IOException {
+ public void save(@NotNull DataOutput out, byte[] value) throws IOException {
out.write(value);
}
@Override
- public byte[] read(DataInput in) throws IOException {
+ public byte[] read(@NotNull DataInput in) throws IOException {
byte[] b = new byte[SIGNATURE_LENGTH];
in.readFully(b);
return b;
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java
index 09de7d3ddcfb..7719e784a4ee 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java
@@ -52,7 +52,12 @@ public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEvent
private Cursor myLastOriginalCursor;
private MouseEvent myPrevPressEvent;
- private JPanel myFocusProxy = new JPanel();
+ private JPanel myFocusProxy = new JPanel(){
+ @Override
+ public String toString() {
+ return "FocusProxy";
+ }
+ };
public IdeGlassPaneImpl(JRootPane rootPane) {
myRootPane = rootPane;
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java
index 9be7a9245544..5103ce761935 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.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.
@@ -17,10 +17,7 @@ package com.intellij.openapi.wm.impl.status;
import com.intellij.ide.util.GotoLineNumberDialog;
import com.intellij.openapi.command.CommandProcessor;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.EditorFactory;
-import com.intellij.openapi.editor.LogicalPosition;
-import com.intellij.openapi.editor.SelectionModel;
+import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
@@ -33,6 +30,7 @@ import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.awt.event.MouseEvent;
+import java.util.List;
public class PositionPanel extends EditorBasedWidget implements StatusBarWidget.Multiframe, StatusBarWidget.TextPresentation, CaretListener, SelectionListener {
private String myText;
@@ -124,6 +122,16 @@ public class PositionPanel extends EditorBasedWidget implements StatusBarWidget.
updatePosition(e.getEditor());
}
+ @Override
+ public void caretAdded(CaretEvent e) {
+ updatePosition(e.getEditor());
+ }
+
+ @Override
+ public void caretRemoved(CaretEvent e) {
+ updatePosition(e.getEditor());
+ }
+
private void updatePosition(final Editor editor) {
if (editor == null) {
myText = "";
@@ -157,12 +165,23 @@ public class PositionPanel extends EditorBasedWidget implements StatusBarWidget.
);
}
else {
- LogicalPosition caret = editor.getCaretModel().getLogicalPosition();
-
- appendLogicalPosition(caret, message);
- if (selectionModel.hasSelection()) {
- int len = Math.abs(selectionModel.getSelectionStart() - selectionModel.getSelectionEnd());
- if (len != 0) message.append("/").append(len);
+ List<Caret> carets = editor.getCaretModel().getAllCarets();
+ if (carets.size() > 1) {
+ message.append(carets.size()).append(" carets (");
+ appendLogicalPosition(carets.get(0).getLogicalPosition(), message);
+ message.append('-');
+ appendLogicalPosition(carets.get(carets.size() - 1).getLogicalPosition(), message);
+ message.append(')');
+ }
+ else {
+ Caret caret = carets.get(0);
+ LogicalPosition caretPosition = caret.getLogicalPosition();
+
+ appendLogicalPosition(caretPosition, message);
+ if (caret.hasSelection()) {
+ int len = Math.abs(caret.getSelectionStart() - caret.getSelectionEnd());
+ if (len != 0) message.append("/").append(len);
+ }
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java
index d4477a330542..8fd1559c61b1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java
@@ -72,8 +72,13 @@ class ToolWindowsWidget extends JLabel implements CustomStatusBarWidget, StatusB
@Override
public boolean dispatch(AWTEvent e) {
if (e instanceof MouseEvent) {
+ MouseEvent mouseEvent = (MouseEvent)e;
+ if (mouseEvent.getComponent() == null || !SwingUtilities.isDescendingFrom(mouseEvent.getComponent(), SwingUtilities.getWindowAncestor(ToolWindowsWidget.this))) {
+ return false;
+ }
+
if (e.getID() == MouseEvent.MOUSE_MOVED && isShowing()) {
- Point p = ((MouseEvent)e).getLocationOnScreen();
+ Point p = mouseEvent.getLocationOnScreen();
Point screen = ToolWindowsWidget.this.getLocationOnScreen();
if (new Rectangle(screen.x - 4, screen.y - 2, getWidth() + 4, getHeight() + 4).contains(p)) {
mouseEntered();
@@ -85,7 +90,7 @@ class ToolWindowsWidget extends JLabel implements CustomStatusBarWidget, StatusB
}
} else if (e.getID() == MouseEvent.MOUSE_EXITED) {
//mouse exits WND
- mouseExited(((MouseEvent)e).getLocationOnScreen());
+ mouseExited(mouseEvent.getLocationOnScreen());
}
}
return false;
diff --git a/platform/platform-impl/src/com/intellij/remote/MutableRemoteCredentials.java b/platform/platform-impl/src/com/intellij/remote/MutableRemoteCredentials.java
new file mode 100644
index 000000000000..5f8d33b8302b
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/MutableRemoteCredentials.java
@@ -0,0 +1,45 @@
+/*
+ * 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.remote;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author traff
+ */
+public interface MutableRemoteCredentials extends RemoteCredentials {
+ void setHost(String host);
+
+ void setPort(int port);
+
+ void setUserName(String userName);
+
+ void setPassword(@Nullable String password);
+
+ void setStorePassword(boolean storePassword);
+
+ void setStorePassphrase(boolean storePassphrase);
+
+ void setAnonymous(boolean anonymous);
+
+ void setPrivateKeyFile(String privateKeyFile);
+
+ void setKnownHostsFile(String knownHostsFile);
+
+ void setPassphrase(@Nullable String passphrase);
+
+ void setUseKeyPair(boolean useKeyPair);
+}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteCancelledException.java b/platform/platform-impl/src/com/intellij/remote/RemoteCancelledException.java
new file mode 100644
index 000000000000..da38b1a56fa7
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteCancelledException.java
@@ -0,0 +1,10 @@
+package com.intellij.remote;
+
+/**
+ * @author traff
+ */
+public class RemoteCancelledException extends RemoteSdkException {
+ public RemoteCancelledException(String s) {
+ super(s);
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java b/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java
new file mode 100644
index 000000000000..a90f4a4df214
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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;
+
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.UserDataHolderBase;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author traff
+ */
+public class RemoteConnectionCredentialsWrapper {
+ public static final String VAGRANT_PREFIX = "vagrant://";
+ public static final String SFTP_DEPLOYMENT_PREFIX = "sftp://";
+
+ 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.putUserData(VAGRANT_BASED_CREDENTIALS, vagrantBasedCredentials);
+ }
+
+
+ private VagrantBasedCredentialsHolder getVagrantCredentials() {
+ return myCredentialsTypeHolder.getUserData(VAGRANT_BASED_CREDENTIALS);
+ }
+
+ public void setPlainSshCredentials(RemoteCredentialsHolder credentials) {
+ myCredentialsTypeHolder.putUserData(PLAIN_SSH_CREDENTIALS, credentials);
+ }
+
+ private RemoteCredentialsHolder getPlainSshCredentials() {
+ return myCredentialsTypeHolder.getUserData(PLAIN_SSH_CREDENTIALS);
+ }
+
+
+ public void setWebDeploymentCredentials(WebDeploymentCredentialsHolder webDeploymentCredentials) {
+ myCredentialsTypeHolder.putUserData(WEB_DEPLOYMENT_BASED_CREDENTIALS, webDeploymentCredentials);
+ }
+
+ private WebDeploymentCredentialsHolder getWebDeploymentCredentials() {
+ return myCredentialsTypeHolder.getUserData(WEB_DEPLOYMENT_BASED_CREDENTIALS);
+ }
+
+ private boolean isVagrantConnection() {
+ return getVagrantCredentials() != null;
+ }
+
+ private boolean isPlainSshConnection() {
+ return getPlainSshCredentials() != null;
+ }
+
+ private boolean isWebDeploymentConnection() {
+ return getWebDeploymentCredentials() != null;
+ }
+
+
+ public Object getConnectionKey() {
+ if (isVagrantConnection()) {
+ return getVagrantCredentials();
+ }
+ else if (isPlainSshConnection()) {
+ return getPlainSshCredentials();
+ }
+ else if (isWebDeploymentConnection()) {
+ return getWebDeploymentCredentials();
+ }
+ else {
+ throw unknownConnectionType();
+ }
+ }
+
+ public void save(final Element rootElement) {
+ switchType(new RemoteSdkConnectionAcceptor() {
+ @Override
+ public void ssh(RemoteCredentialsHolder cred) {
+ cred.save(rootElement);
+ }
+
+ @Override
+ public void vagrant(VagrantBasedCredentialsHolder cred) {
+ cred.save(rootElement);
+ }
+
+ @Override
+ public void deployment(WebDeploymentCredentialsHolder cred) {
+ cred.save(rootElement);
+ }
+ });
+ }
+
+ public static IllegalStateException unknownConnectionType() {
+ return new IllegalStateException("Unknown connection type"); //TODO
+ }
+
+ public void copyTo(RemoteConnectionCredentialsWrapper copy) {
+ copy.myCredentialsTypeHolder = new UserDataHolderBase();
+ copy.setPlainSshCredentials(getPlainSshCredentials());
+ copy.setVagrantConnectionType(getVagrantCredentials());
+ copy.setWebDeploymentCredentials(getWebDeploymentCredentials());
+ }
+
+ public String getId() {
+ if (isVagrantConnection()) {
+ @NotNull VagrantBasedCredentialsHolder cred = getVagrantCredentials();
+
+ return VAGRANT_PREFIX + cred.getVagrantFolder();
+ }
+ else if (isPlainSshConnection()) {
+ RemoteCredentials cred = getPlainSshCredentials();
+
+ return constructSshCredentialsFullPath(cred);
+ }
+ else if (isWebDeploymentConnection()) {
+ WebDeploymentCredentialsHolder cred = getWebDeploymentCredentials();
+ return constructSftpCredentialsFullPath(cred.getSshCredentials());
+ }
+ else {
+ throw unknownConnectionType();
+ }
+ }
+
+ private static String constructSftpCredentialsFullPath(RemoteCredentials cred) {
+ return SFTP_DEPLOYMENT_PREFIX + cred.getUserName() + "@" + cred.getHost() + ":" + cred.getPort();
+ }
+
+
+ public static String constructSshCredentialsFullPath(RemoteCredentials cred) {
+ return RemoteSdkCredentialsHolder.SSH_PREFIX + cred.getUserName() + "@" + cred.getHost() + ":" + cred.getPort();
+ }
+
+ public void switchType(RemoteSdkConnectionAcceptor acceptor) {
+ if (isVagrantConnection()) {
+ acceptor.vagrant(getVagrantCredentials());
+ }
+ else if (isPlainSshConnection()) {
+ acceptor.ssh(getPlainSshCredentials());
+ }
+ else if (isWebDeploymentConnection()) {
+ acceptor.deployment(getWebDeploymentCredentials());
+ }
+ else {
+ throw unknownConnectionType();
+ }
+ }
+
+ public interface RemoteSdkConnectionAcceptor {
+ void ssh(RemoteCredentialsHolder cred);
+ void vagrant(VagrantBasedCredentialsHolder cred);
+ void deployment(WebDeploymentCredentialsHolder cred);
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteCredentials.java b/platform/platform-impl/src/com/intellij/remote/RemoteCredentials.java
new file mode 100644
index 000000000000..74f1be780ea8
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteCredentials.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.intellij.remote;
+
+import com.intellij.util.xmlb.annotations.Transient;
+
+/**
+ * @author traff
+ */
+public interface RemoteCredentials {
+ String getHost();
+
+ int getPort();
+
+ @Transient
+ String getUserName();
+
+ String getPassword();
+
+ @Transient
+ String getPassphrase();
+
+ boolean isUseKeyPair();
+
+ boolean isAnonymous();
+
+ String getPrivateKeyFile();
+
+ boolean isStorePassword();
+
+ boolean isStorePassphrase();
+
+ String getKnownHostsFile();
+}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remote/RemoteCredentialsHolder.java
new file mode 100644
index 000000000000..5f5efb7276ae
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteCredentialsHolder.java
@@ -0,0 +1,260 @@
+/*
+ * 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.remote;
+
+import com.intellij.openapi.util.PasswordUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.remote.MutableRemoteCredentials;
+import com.intellij.remote.RemoteCredentials;
+import com.intellij.remote.RemoteSdkCredentials;
+import com.intellij.util.xmlb.annotations.Transient;
+import org.jdom.Element;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author michael.golubev
+ */
+public class RemoteCredentialsHolder implements MutableRemoteCredentials {
+
+ public static final String HOST = "HOST";
+ public static final String PORT = "PORT";
+ public static final String ANONYMOUS = "ANONYMOUS";
+ public static final String USERNAME = "USERNAME";
+ public static final String PASSWORD = "PASSWORD";
+ public static final String USE_KEY_PAIR = "USE_KEY_PAIR";
+ public static final String PRIVATE_KEY_FILE = "PRIVATE_KEY_FILE";
+ public static final String KNOWN_HOSTS_FILE = "MY_KNOWN_HOSTS_FILE";
+ public static final String PASSPHRASE = "PASSPHRASE";
+
+ private String myHost;
+ private int myPort;
+ private boolean myAnonymous;
+ private String myUserName;
+ private String myPassword;
+ private boolean myUseKeyPair;
+ private String myPrivateKeyFile;
+ private String myKnownHostsFile;
+ private String myPassphrase;
+ private boolean myStorePassword;
+ private boolean myStorePassphrase;
+
+ @Override
+ public String getHost() {
+ return myHost;
+ }
+
+ public void setHost(String host) {
+ myHost = host;
+ }
+
+ @Override
+ public int getPort() {
+ return myPort;
+ }
+
+ public void setPort(int port) {
+ myPort = port;
+ }
+
+ @Override
+ @Transient
+ public String getUserName() {
+ return myUserName;
+ }
+
+ public void setUserName(String userName) {
+ myUserName = userName;
+ }
+
+ @Override
+ public String getPassword() {
+ return myPassword;
+ }
+
+ public void setPassword(String password) {
+ myPassword = password;
+ }
+
+ public void setStorePassword(boolean storePassword) {
+ myStorePassword = storePassword;
+ }
+
+ public void setStorePassphrase(boolean storePassphrase) {
+ myStorePassphrase = storePassphrase;
+ }
+
+ @Override
+ public boolean isStorePassword() {
+ return myStorePassword;
+ }
+
+ @Override
+ public boolean isStorePassphrase() {
+ return myStorePassphrase;
+ }
+
+ @Override
+ public boolean isAnonymous() {
+ return myAnonymous;
+ }
+
+ public void setAnonymous(boolean anonymous) {
+ myAnonymous = anonymous;
+ }
+
+ @Override
+ public String getPrivateKeyFile() {
+ return myPrivateKeyFile;
+ }
+
+ public void setPrivateKeyFile(String privateKeyFile) {
+ myPrivateKeyFile = privateKeyFile;
+ }
+
+ @Override
+ public String getKnownHostsFile() {
+ return myKnownHostsFile;
+ }
+
+ public void setKnownHostsFile(String knownHostsFile) {
+ myKnownHostsFile = knownHostsFile;
+ }
+
+ @Override
+ @Transient
+ public String getPassphrase() {
+ return myPassphrase;
+ }
+
+ public void setPassphrase(String passphrase) {
+ myPassphrase = passphrase;
+ }
+
+ @Override
+ public boolean isUseKeyPair() {
+ return myUseKeyPair;
+ }
+
+ public void setUseKeyPair(boolean useKeyPair) {
+ myUseKeyPair = useKeyPair;
+ }
+
+ public String getSerializedUserName() {
+ if (myAnonymous || myUserName == null) return "";
+ return myUserName;
+ }
+
+ public void setSerializedUserName(String userName) {
+ if (StringUtil.isEmpty(userName)) {
+ myUserName = null;
+ }
+ else {
+ myUserName = userName;
+ }
+ }
+
+ public String getSerializedPassword() {
+ if (myAnonymous) return "";
+
+ if (myStorePassword) {
+ return PasswordUtil.encodePassword(myPassword);
+ }
+ else {
+ return "";
+ }
+ }
+
+ public void setSerializedPassword(String serializedPassword) {
+ if (!StringUtil.isEmpty(serializedPassword)) {
+ myPassword = PasswordUtil.decodePassword(serializedPassword);
+ myStorePassword = true;
+ }
+ else {
+ myPassword = null;
+ }
+ }
+
+ @Nullable
+ public String getSerializedPassphrase() {
+ if (myStorePassphrase) {
+ return PasswordUtil.encodePassword(myPassphrase);
+ }
+ else {
+ return "";
+ }
+ }
+
+ public void setSerializedPassphrase(String serializedPassphrase) {
+ if (!StringUtil.isEmpty(serializedPassphrase)) {
+ myPassphrase = PasswordUtil.decodePassword(serializedPassphrase);
+ myStorePassphrase = true;
+ }
+ else {
+ myPassphrase = null;
+ myStorePassphrase = false;
+ }
+ }
+
+ public void copyRemoteCredentialsTo(RemoteSdkCredentials to) {
+ to.setHost(getHost());
+ to.setPort(getPort());
+ to.setAnonymous(isAnonymous());
+ to.setUserName(getUserName());
+ to.setPassword(getPassword());
+ to.setUseKeyPair(isUseKeyPair());
+ to.setPrivateKeyFile(getPrivateKeyFile());
+ to.setKnownHostsFile(getKnownHostsFile());
+ to.setStorePassword(isStorePassword());
+ to.setStorePassphrase(isStorePassphrase());
+ }
+
+ public void load(Element element) {
+ setHost(element.getAttributeValue(HOST));
+ setPort(StringUtil.parseInt(element.getAttributeValue(PORT), 22));
+ setAnonymous(StringUtil.parseBoolean(element.getAttributeValue(ANONYMOUS), false));
+ setSerializedUserName(element.getAttributeValue(USERNAME));
+ setSerializedPassword(element.getAttributeValue(PASSWORD));
+ setPrivateKeyFile(StringUtil.nullize(element.getAttributeValue(PRIVATE_KEY_FILE)));
+ setKnownHostsFile(StringUtil.nullize(element.getAttributeValue(KNOWN_HOSTS_FILE)));
+ setSerializedPassphrase(element.getAttributeValue(PASSPHRASE));
+ setUseKeyPair(StringUtil.parseBoolean(element.getAttributeValue(USE_KEY_PAIR), false));
+ }
+
+ public void save(Element rootElement) {
+ rootElement.setAttribute(HOST, StringUtil.notNullize(getHost()));
+ rootElement.setAttribute(PORT, Integer.toString(getPort()));
+ rootElement.setAttribute(ANONYMOUS, Boolean.toString(isAnonymous()));
+ rootElement.setAttribute(USERNAME, getSerializedUserName());
+ rootElement.setAttribute(PASSWORD, getSerializedPassword());
+ rootElement.setAttribute(PRIVATE_KEY_FILE, StringUtil.notNullize(getPrivateKeyFile()));
+ rootElement.setAttribute(KNOWN_HOSTS_FILE, StringUtil.notNullize(getKnownHostsFile()));
+ rootElement.setAttribute(PASSPHRASE, getSerializedPassphrase());
+ rootElement.setAttribute(USE_KEY_PAIR, Boolean.toString(isUseKeyPair()));
+ }
+
+ public void copyFrom(RemoteCredentials from) {
+ setHost(from.getHost());
+ setPort(from.getPort());
+ setAnonymous(from.isAnonymous());
+ setUserName(from.getUserName());
+ setPassword(from.getPassword());
+ setUseKeyPair(from.isUseKeyPair());
+ setPrivateKeyFile(from.getPrivateKeyFile());
+ setKnownHostsFile(from.getKnownHostsFile());
+ setStorePassword(from.isStorePassword());
+ setStorePassphrase(from.isStorePassphrase());
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteFile.java b/platform/platform-impl/src/com/intellij/remote/RemoteFile.java
new file mode 100644
index 000000000000..4a2e11379364
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteFile.java
@@ -0,0 +1,110 @@
+package com.intellij.remote;
+
+import com.intellij.openapi.util.io.FileUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author traff
+ */
+public class RemoteFile {
+
+ private final boolean myWin;
+ private final String myPath;
+
+ public RemoteFile(@NotNull String path, boolean isWin) {
+ myPath = toSystemDependent(path, isWin);
+ myWin = isWin;
+ }
+
+ public RemoteFile(@NotNull String parent, String child) {
+ this(resolveChild(parent, child, isWindowsPath(parent)), isWindowsPath(parent));
+ }
+
+ public RemoteFile(@NotNull String parent, String child, boolean isWin) {
+ this(resolveChild(parent, child, isWin), isWin);
+ }
+
+ @Nullable
+ public String getName() {
+ int ind = myPath.lastIndexOf(getSeparator(myWin));
+ if (ind != -1 && ind < myPath.length() - 1) { //not last char
+ return myPath.substring(ind + 1);
+ }
+ else {
+ return null;
+ }
+ }
+
+ private static String resolveChild(@NotNull String parent, @NotNull String child, boolean win) {
+ String separator = getSeparator(win);
+
+ String path;
+ if (parent.endsWith(separator)) {
+ path = parent + child;
+ }
+ else {
+ path = parent + separator + child;
+ }
+ return path;
+ }
+
+ private static String getSeparator(boolean win) {
+ String separator;
+ if (win) {
+ separator = "\\";
+ }
+ else {
+ separator = "/";
+ }
+ return separator;
+ }
+
+
+ public String getPath() {
+ return myPath;
+ }
+
+ public boolean isWin() {
+ return isWindowsPath(myPath);
+ }
+
+ public static boolean isWindowsPath(@NotNull String path) {
+ path = RemoteSdkCredentialsHolder.getInterpreterPathFromFullPath(path);
+
+ return (path.length() > 1 && path.charAt(1) == ':');
+ }
+
+ private static String toSystemDependent(@NotNull String path, boolean isWin) {
+ char separator = isWin ? '\\' : '/';
+ return FileUtil.toSystemIndependentName(path).replace('/', separator);
+ }
+
+ public static RemoteFileBuilder detectSystemByPath(@NotNull String path) {
+ return new RemoteFileBuilder(isWindowsPath(path));
+ }
+
+ public static RemoteFile createRemoteFile(String path, String script) {
+ return detectSystemByPath(path).createRemoteFile(path, script);
+ }
+
+ public static RemoteFile createRemoteFile(final String path, final String script, final boolean isWindows) {
+ return new RemoteFileBuilder(isWindows).createRemoteFile(path, script);
+ }
+
+ public static class RemoteFileBuilder {
+ private final boolean isWin;
+
+ private RemoteFileBuilder(boolean win) {
+ isWin = win;
+ }
+
+ public RemoteFile createRemoteFile(String path) {
+ return new RemoteFile(path, isWin);
+ }
+
+ public RemoteFile createRemoteFile(String path, String child) {
+ return new RemoteFile(path, child, isWin);
+ }
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteProcessHandlerBase.java b/platform/platform-impl/src/com/intellij/remote/RemoteProcessHandlerBase.java
new file mode 100644
index 000000000000..efeb9bf176e6
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteProcessHandlerBase.java
@@ -0,0 +1,20 @@
+package com.intellij.remote;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.remote.RemoteSdkException;
+import com.intellij.util.PathMappingSettings;
+
+import java.util.List;
+
+/**
+ * @author traff
+ */
+public interface RemoteProcessHandlerBase {
+ PathMappingSettings getMappingSettings();
+
+ Pair<String, Integer> obtainRemoteSocket() throws RemoteSdkException;
+
+ void addRemoteForwarding(int remotePort, int localPort);
+
+ List<PathMappingSettings.PathMapping> getFileMappings();
+}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkAdditionalData2.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkAdditionalData.java
index 92ec30233a6c..4cb6707f7577 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkAdditionalData2.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkAdditionalData.java
@@ -13,17 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.remotesdk2;
+package com.intellij.remote;
import com.intellij.openapi.projectRoots.SdkAdditionalData;
-import com.intellij.remotesdk.RemoteSdkCredentials;
-import com.intellij.remotesdk.RemoteSdkCredentialsHolder;
-import com.intellij.remotesdk.RemoteSdkProperties;
+import org.jetbrains.annotations.NotNull;
/**
* @author traff
*/
-public interface RemoteSdkAdditionalData2<T extends RemoteSdkCredentials>
+public interface RemoteSdkAdditionalData<T extends RemoteSdkCredentials>
extends SdkAdditionalData, RemoteSdkProducer<T>, RemoteSdkProperties {
void completeInitialization();
@@ -33,9 +31,13 @@ public interface RemoteSdkAdditionalData2<T extends RemoteSdkCredentials>
String getFullInterpreterPath();
+ void setVagrantConnectionType(@NotNull VagrantBasedCredentialsHolder vagrantBasedCredentials);
+
/**
* This method switches to use of ssh-credentials based data
* @param credentials credentials that specify connection
*/
- void setSshCredentials(RemoteSdkCredentialsHolder credentials);
+ void setSshCredentials(@NotNull RemoteCredentialsHolder credentials);
+
+ void setDeploymentConnectionType(@NotNull WebDeploymentCredentialsHolder credentials);
}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentials.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentials.java
new file mode 100644
index 000000000000..876f82771025
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentials.java
@@ -0,0 +1,11 @@
+package com.intellij.remote;
+
+import com.intellij.remote.MutableRemoteCredentials;
+import com.intellij.remote.RemoteSdkProperties;
+
+/**
+ * @author traff
+ */
+public interface RemoteSdkCredentials extends MutableRemoteCredentials, RemoteSdkProperties {
+ String getFullInterpreterPath();
+}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentialsBuilder.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsBuilder.java
index 57ea1136527b..59e9cf02d7ba 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentialsBuilder.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsBuilder.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.remotesdk;
+package com.intellij.remote;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java
index 88663598f9c6..e936686e0840 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentialsHolder.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java
@@ -1,11 +1,9 @@
-package com.intellij.remotesdk;
+package com.intellij.remote;
-import com.intellij.openapi.util.text.StringUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.LinkedList;
import java.util.List;
/**
@@ -13,11 +11,6 @@ import java.util.List;
*/
public class RemoteSdkCredentialsHolder extends RemoteCredentialsHolder implements RemoteSdkCredentials {
public static final String SSH_PREFIX = "ssh://";
- private static final String INTERPRETER_PATH = "INTERPRETER_PATH";
- private static final String HELPERS_PATH = "HELPERS_PATH";
- private static final String REMOTE_ROOTS = "REMOTE_ROOTS";
- private static final String REMOTE_PATH = "REMOTE_PATH";
- private static final String INITIALIZED = "INITIALIZED";
@NotNull
private final RemoteSdkPropertiesHolder myRemoteSdkProperties;
@@ -30,7 +23,6 @@ public class RemoteSdkCredentialsHolder extends RemoteCredentialsHolder implemen
return SSH_PREFIX + cred.getUserName() + "@" + cred.getHost() + ":" + cred.getPort() + cred.getInterpreterPath();
}
-
/**
* Extracts interpreter path from full path generated by method getFullInterpreterPath
* Returns fullPath as fallback
@@ -118,7 +110,7 @@ public class RemoteSdkCredentialsHolder extends RemoteCredentialsHolder implemen
@Override
public String getFullInterpreterPath() {
- return myRemoteSdkProperties.getFullInterpreterPath();
+ return constructSshCredentialsSdkFullPath(this);
}
@Override
@@ -127,6 +119,11 @@ public class RemoteSdkCredentialsHolder extends RemoteCredentialsHolder implemen
}
@Override
+ public String getSdkId() {
+ return myRemoteSdkProperties.getSdkId();
+ }
+
+ @Override
public boolean isInitialized() {
return myRemoteSdkProperties.isInitialized();
}
@@ -138,64 +135,27 @@ public class RemoteSdkCredentialsHolder extends RemoteCredentialsHolder implemen
public static boolean isRemoteSdk(@Nullable String path) {
if (path != null) {
- return path.startsWith(SSH_PREFIX);
+ return path.startsWith(SSH_PREFIX) || path.startsWith(RemoteConnectionCredentialsWrapper.VAGRANT_PREFIX) ||
+ path.startsWith(RemoteConnectionCredentialsWrapper.SFTP_DEPLOYMENT_PREFIX);
}
else {
return false;
}
}
- public void loadRemoteSdkCredentials(Element element) {
- setHost(element.getAttributeValue(HOST));
- setPort(StringUtil.parseInt(element.getAttributeValue(PORT), 22));
- setAnonymous(StringUtil.parseBoolean(element.getAttributeValue(ANONYMOUS), false));
- setSerializedUserName(element.getAttributeValue(USERNAME));
- setSerializedPassword(element.getAttributeValue(PASSWORD));
- setPrivateKeyFile(StringUtil.nullize(element.getAttributeValue(PRIVATE_KEY_FILE)));
- setKnownHostsFile(StringUtil.nullize(element.getAttributeValue(KNOWN_HOSTS_FILE)));
- setSerializedPassphrase(element.getAttributeValue(PASSPHRASE));
- setUseKeyPair(StringUtil.parseBoolean(element.getAttributeValue(USE_KEY_PAIR), false));
-
- setInterpreterPath(StringUtil.nullize(element.getAttributeValue(INTERPRETER_PATH)));
- setHelpersPath(StringUtil.nullize(element.getAttributeValue(HELPERS_PATH)));
- setRemoteRoots(loadStringsList(element, REMOTE_ROOTS, REMOTE_PATH));
+ @Override
+ public void load(Element element) {
+ super.load(element);
- setInitialized(StringUtil.parseBoolean(element.getAttributeValue(INITIALIZED), true));
+ myRemoteSdkProperties.load(element);
}
- protected static List<String> loadStringsList(Element element, String rootName, String attrName) {
- final List<String> paths = new LinkedList<String>();
- if (element != null) {
- @NotNull final List list = element.getChildren(rootName);
- for (Object o : list) {
- paths.add(((Element)o).getAttribute(attrName).getValue());
- }
- }
- return paths;
- }
+ @Override
+ public void save(Element rootElement) {
+ super.save(rootElement);
- public void saveRemoteSdkData(Element rootElement) {
- rootElement.setAttribute(HOST, StringUtil.notNullize(getHost()));
- rootElement.setAttribute(PORT, Integer.toString(getPort()));
- rootElement.setAttribute(ANONYMOUS, Boolean.toString(isAnonymous()));
- rootElement.setAttribute(USERNAME, getSerializedUserName());
- rootElement.setAttribute(PASSWORD, getSerializedPassword());
- rootElement.setAttribute(PRIVATE_KEY_FILE, StringUtil.notNullize(getPrivateKeyFile()));
- rootElement.setAttribute(KNOWN_HOSTS_FILE, StringUtil.notNullize(getKnownHostsFile()));
- rootElement.setAttribute(PASSPHRASE, getSerializedPassphrase());
- rootElement.setAttribute(USE_KEY_PAIR, Boolean.toString(isUseKeyPair()));
-
- rootElement.setAttribute(INTERPRETER_PATH, StringUtil.notNullize(getInterpreterPath()));
- rootElement.setAttribute(HELPERS_PATH, StringUtil.notNullize(getHelpersPath()));
-
- rootElement.setAttribute(INITIALIZED, Boolean.toString(isInitialized()));
-
- for (String remoteRoot : getRemoteRoots()) {
- final Element child = new Element(REMOTE_ROOTS);
- child.setAttribute(REMOTE_PATH, remoteRoot);
- rootElement.addContent(child);
- }
+ myRemoteSdkProperties.save(rootElement);
}
@@ -268,8 +228,8 @@ public class RemoteSdkCredentialsHolder extends RemoteCredentialsHolder implemen
'}';
}
- public void copyTo(RemoteSdkCredentialsHolder to) {
- super.copyTo(to);
+ public void copyRemoteSdkCredentialsTo(RemoteSdkCredentialsHolder to) {
+ super.copyRemoteCredentialsTo(to);
myRemoteSdkProperties.copyTo(to.getRemoteSdkProperties());
}
}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkException.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkException.java
new file mode 100644
index 000000000000..fd6f5440b782
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkException.java
@@ -0,0 +1,49 @@
+package com.intellij.remote;
+
+import com.intellij.execution.ExecutionException;
+
+import java.net.NoRouteToHostException;
+
+/**
+ * @author traff
+ */
+public class RemoteSdkException extends ExecutionException {
+ private final boolean myNoRouteToHost;
+ private final boolean myAuthFailed;
+
+ public RemoteSdkException(String s, Throwable throwable) {
+ super(s, throwable);
+ myNoRouteToHost = throwable instanceof NoRouteToHostException;
+ myAuthFailed = false;
+ }
+
+ public RemoteSdkException(String s) {
+ super(s);
+ myAuthFailed = false;
+ myNoRouteToHost = false;
+ }
+
+ public boolean isNoRouteToHost() {
+ return myNoRouteToHost;
+ }
+
+ public boolean isAuthFailed() {
+ return myAuthFailed;
+ }
+
+ public String getMessage() {
+ if (myNoRouteToHost) {
+ return getCause().getMessage();
+ }
+ else if (myAuthFailed) {
+ return "Authentication failed";
+ }
+ else {
+ return super.getMessage();
+ }
+ }
+
+ public static RemoteSdkException cantObtainRemoteCredentials(Throwable e) {
+ return new RemoteSdkException("Cant obtain remote credentials", e);
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkFactory2.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkFactory.java
index cc3d06af7770..dc28679937fe 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkFactory2.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkFactory.java
@@ -13,11 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.remotesdk2;
+package com.intellij.remote;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.remotesdk.RemoteInterpreterException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -27,9 +26,9 @@ import java.util.Collection;
/**
* @author traff
*/
-public interface RemoteSdkFactory2<T extends RemoteSdkAdditionalData2> {
+public interface RemoteSdkFactory<T extends RemoteSdkAdditionalData> {
Sdk createRemoteSdk(@Nullable Project project, @NotNull T data, @Nullable String sdkName, Collection<Sdk> existingSdks)
- throws RemoteInterpreterException;
+ throws RemoteSdkException;
Sdk createUnfinished(T data, Collection<Sdk> existingSdks);
diff --git a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkProducer.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkProducer.java
index 72c585b642cd..cd5c00ed9e2a 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkProducer.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkProducer.java
@@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.remotesdk2;
+package com.intellij.remote;
-import com.intellij.remotesdk.RemoteSdkCredentials;
import com.intellij.util.Consumer;
/**
@@ -24,7 +23,7 @@ import com.intellij.util.Consumer;
public interface RemoteSdkProducer<T extends RemoteSdkCredentials> {
T getRemoteSdkCredentials() throws InterruptedException;
- void produceRemoteSdkCredentials(Consumer<T> remoteSdkConsumer);
+ void produceRemoteSdkCredentials(Consumer<T> remoteSdkCredentialsConsumer);
Object getRemoteSdkDataKey();
}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkProperties.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java
index 5e98352accf6..7d132578a6d4 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkProperties.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.remotesdk;
+package com.intellij.remote;
import java.util.List;
@@ -43,10 +43,10 @@ public interface RemoteSdkProperties {
void setHelpersVersionChecked(boolean helpersVersionChecked);
- String getFullInterpreterPath();
-
void setSdkId(String sdkId);
+ String getSdkId();
+
@Deprecated
boolean isInitialized();
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkPropertiesHolder.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java
index 11f350ca10c5..bc5fad1e4fff 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkPropertiesHolder.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java
@@ -13,7 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.remotesdk;
+package com.intellij.remote;
+
+import com.intellij.openapi.util.JDOMExternalizer;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jdom.Element;
import java.util.ArrayList;
import java.util.List;
@@ -22,6 +26,12 @@ import java.util.List;
* @author traff
*/
public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
+ private static final String INTERPRETER_PATH = "INTERPRETER_PATH";
+ private static final String HELPERS_PATH = "HELPERS_PATH";
+ private static final String REMOTE_ROOTS = "REMOTE_ROOTS";
+ private static final String REMOTE_PATH = "REMOTE_PATH";
+ private static final String INITIALIZED = "INITIALIZED";
+
private String mySdkId;
private String myInterpreterPath;
@@ -93,15 +103,14 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
myHelpersVersionChecked = helpersVersionChecked;
}
- @Override
- public String getFullInterpreterPath() {
- return mySdkId;
- }
-
public void setSdkId(String sdkId) {
mySdkId = sdkId;
}
+ public String getSdkId() {
+ return mySdkId;
+ }
+
@Override
public boolean isInitialized() {
return myInitialized;
@@ -113,7 +122,7 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
}
- public void copyTo(RemoteSdkPropertiesHolder copy) {
+ public void copyTo(RemoteSdkProperties copy) {
copy.setInterpreterPath(getInterpreterPath());
copy.setHelpersPath(getHelpersPath());
copy.setHelpersVersionChecked(isHelpersVersionChecked());
@@ -122,4 +131,26 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
copy.setInitialized(isInitialized());
}
+
+ public void save(Element rootElement) {
+ rootElement.setAttribute(INTERPRETER_PATH, StringUtil.notNullize(getInterpreterPath()));
+ rootElement.setAttribute(HELPERS_PATH, StringUtil.notNullize(getHelpersPath()));
+
+ rootElement.setAttribute(INITIALIZED, Boolean.toString(isInitialized()));
+
+ for (String remoteRoot : getRemoteRoots()) {
+ final Element child = new Element(REMOTE_ROOTS);
+ child.setAttribute(REMOTE_PATH, remoteRoot);
+ rootElement.addContent(child);
+ }
+ }
+
+ public void load(Element element) {
+ setInterpreterPath(StringUtil.nullize(element.getAttributeValue(INTERPRETER_PATH)));
+ setHelpersPath(StringUtil.nullize(element.getAttributeValue(HELPERS_PATH)));
+
+ setRemoteRoots(JDOMExternalizer.loadStringsList(element, REMOTE_ROOTS, REMOTE_PATH));
+
+ setInitialized(StringUtil.parseBoolean(element.getAttributeValue(INITIALIZED), true));
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSshProcess.java b/platform/platform-impl/src/com/intellij/remote/RemoteSshProcess.java
new file mode 100644
index 000000000000..b9090bcd3ee8
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSshProcess.java
@@ -0,0 +1,22 @@
+package com.intellij.remote;
+
+import com.intellij.execution.process.SelfKiller;
+
+/**
+ * @author traff
+ */
+abstract public class RemoteSshProcess extends Process implements SelfKiller {
+ /**
+ * Makes host:localPort server which is available on local side available on remote side as localhost:remotePort.
+ */
+ public abstract void addRemoteTunnel(int remotePort, String host, int localPort) throws RemoteSdkException;
+
+ /**
+ * Makes host:remotePort server which is available on remote side available on local side as localhost:localPort.
+ */
+ public abstract void addLocalTunnel(int localPort, String host, int remotePort) throws RemoteSdkException;
+
+ public abstract boolean hasPty();
+
+ public abstract boolean sendCtrlC();
+}
diff --git a/platform/platform-impl/src/com/intellij/remote/VagrantBasedCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remote/VagrantBasedCredentialsHolder.java
new file mode 100644
index 000000000000..d5f867c5836d
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/VagrantBasedCredentialsHolder.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.remote;
+
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+
+/**
+* @author traff
+*/
+public class VagrantBasedCredentialsHolder {
+ private static final String VAGRANT_FOLDER = "VAGRANT_FOLDER";
+ private String myVagrantFolder;
+
+ public VagrantBasedCredentialsHolder() {
+ }
+
+ public VagrantBasedCredentialsHolder(@NotNull String folder) {
+ myVagrantFolder = folder;
+ }
+
+ public void setVagrantFolder(String vagrantFolder) {
+ myVagrantFolder = vagrantFolder;
+ }
+
+ @NotNull
+ public String getVagrantFolder() {
+ return myVagrantFolder;
+ }
+
+ public void load(Element element) {
+ setVagrantFolder(element.getAttributeValue(VAGRANT_FOLDER));
+ }
+
+ public void save(Element element) {
+ element.setAttribute(VAGRANT_FOLDER, getVagrantFolder());
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/remote/WebDeploymentCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remote/WebDeploymentCredentialsHolder.java
new file mode 100644
index 000000000000..5db969a6592c
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/WebDeploymentCredentialsHolder.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.remote;
+
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author traff
+ */
+public class WebDeploymentCredentialsHolder {
+ public static final String WEB_SERVER_CONFIG_ID = "WEB_SERVER_CONFIG_ID";
+
+ private String myWebServerConfigId;
+ private final RemoteCredentialsHolder myRemoteCredentials = new RemoteCredentialsHolder();
+
+
+ public WebDeploymentCredentialsHolder() {
+ }
+
+ public WebDeploymentCredentialsHolder(@NotNull String webServerConfigId, @NotNull RemoteCredentials remoteCredentials) {
+ myWebServerConfigId = webServerConfigId;
+ myRemoteCredentials.copyFrom(remoteCredentials);
+ }
+
+ @NotNull
+ public String getWebServerConfigId() {
+ return myWebServerConfigId;
+ }
+
+ public void setWebServerConfigId(@NotNull String webServerConfigId) {
+ myWebServerConfigId = webServerConfigId;
+ }
+
+ public void load(Element element) {
+ myRemoteCredentials.load(element);
+ setWebServerConfigId(element.getAttributeValue(WEB_SERVER_CONFIG_ID));
+ }
+
+ public void save(Element element) {
+ element.setAttribute(WEB_SERVER_CONFIG_ID, getWebServerConfigId());
+
+ myRemoteCredentials.save(element);
+ }
+
+ public RemoteCredentials getSshCredentials() {
+ return myRemoteCredentials;
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/MutableRemoteCredentials.java b/platform/platform-impl/src/com/intellij/remotesdk/MutableRemoteCredentials.java
index e52d8d3337fb..0b630fec6a8b 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/MutableRemoteCredentials.java
+++ b/platform/platform-impl/src/com/intellij/remotesdk/MutableRemoteCredentials.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,31 +15,9 @@
*/
package com.intellij.remotesdk;
-import org.jetbrains.annotations.Nullable;
-
/**
+ * @deprecated Remove in IDEA 14
* @author traff
*/
-public interface MutableRemoteCredentials extends RemoteCredentials {
- void setHost(String host);
-
- void setPort(int port);
-
- void setUserName(String userName);
-
- void setPassword(@Nullable String password);
-
- void setStorePassword(boolean storePassword);
-
- void setStorePassphrase(boolean storePassphrase);
-
- void setAnonymous(boolean anonymous);
-
- void setPrivateKeyFile(String privateKeyFile);
-
- void setKnownHostsFile(String knownHostsFile);
-
- void setPassphrase(@Nullable String passphrase);
-
- void setUseKeyPair(boolean useKeyPair);
+public interface MutableRemoteCredentials extends com.intellij.remote.MutableRemoteCredentials {
}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCancelledException.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCancelledException.java
index eeded52aad2e..2a249209b8e8 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCancelledException.java
+++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCancelledException.java
@@ -1,9 +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.remotesdk;
/**
+ * @deprecated Remove in IDEA 14
+ *
* @author traff
*/
-public class RemoteCancelledException extends RemoteInterpreterException {
+public class RemoteCancelledException extends com.intellij.remote.RemoteCancelledException {
public RemoteCancelledException(String s) {
super(s);
}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentials.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentials.java
index bb7494044beb..e6be766ca826 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentials.java
+++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentials.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,33 +15,10 @@
*/
package com.intellij.remotesdk;
-import com.intellij.util.xmlb.annotations.Transient;
-
/**
+ * @deprecated Remove in IDEA 14
+ *
* @author traff
*/
-public interface RemoteCredentials {
- String getHost();
-
- int getPort();
-
- @Transient
- String getUserName();
-
- String getPassword();
-
- @Transient
- String getPassphrase();
-
- boolean isUseKeyPair();
-
- boolean isAnonymous();
-
- String getPrivateKeyFile();
-
- boolean isStorePassword();
-
- boolean isStorePassphrase();
-
- String getKnownHostsFile();
+public interface RemoteCredentials extends com.intellij.remote.RemoteCredentials {
}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentialsHolder.java
index d0e7e97902f2..886052957f32 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentialsHolder.java
+++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentialsHolder.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,205 +15,10 @@
*/
package com.intellij.remotesdk;
-import com.intellij.openapi.util.PasswordUtil;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.xmlb.annotations.Transient;
-import org.jetbrains.annotations.Nullable;
-
/**
- * @author michael.golubev
+ * @deprecated Remove in IDEA 14
+ *
+ * @author traff
*/
-public class RemoteCredentialsHolder implements MutableRemoteCredentials {
-
- public static final String HOST = "HOST";
- public static final String PORT = "PORT";
- public static final String ANONYMOUS = "ANONYMOUS";
- public static final String USERNAME = "USERNAME";
- public static final String PASSWORD = "PASSWORD";
- public static final String USE_KEY_PAIR = "USE_KEY_PAIR";
- public static final String PRIVATE_KEY_FILE = "PRIVATE_KEY_FILE";
- public static final String KNOWN_HOSTS_FILE = "MY_KNOWN_HOSTS_FILE";
- public static final String PASSPHRASE = "PASSPHRASE";
-
- private String myHost;
- private int myPort;
- private boolean myAnonymous;
- private String myUserName;
- private String myPassword;
- private boolean myUseKeyPair;
- private String myPrivateKeyFile;
- private String myKnownHostsFile;
- private String myPassphrase;
- private boolean myStorePassword;
- private boolean myStorePassphrase;
-
- @Override
- public String getHost() {
- return myHost;
- }
-
- public void setHost(String host) {
- myHost = host;
- }
-
- @Override
- public int getPort() {
- return myPort;
- }
-
- public void setPort(int port) {
- myPort = port;
- }
-
- @Override
- @Transient
- public String getUserName() {
- return myUserName;
- }
-
- public void setUserName(String userName) {
- myUserName = userName;
- }
-
- @Override
- public String getPassword() {
- return myPassword;
- }
-
- public void setPassword(String password) {
- myPassword = password;
- }
-
- public void setStorePassword(boolean storePassword) {
- myStorePassword = storePassword;
- }
-
- public void setStorePassphrase(boolean storePassphrase) {
- myStorePassphrase = storePassphrase;
- }
-
- @Override
- public boolean isStorePassword() {
- return myStorePassword;
- }
-
- @Override
- public boolean isStorePassphrase() {
- return myStorePassphrase;
- }
-
- @Override
- public boolean isAnonymous() {
- return myAnonymous;
- }
-
- public void setAnonymous(boolean anonymous) {
- myAnonymous = anonymous;
- }
-
- @Override
- public String getPrivateKeyFile() {
- return myPrivateKeyFile;
- }
-
- public void setPrivateKeyFile(String privateKeyFile) {
- myPrivateKeyFile = privateKeyFile;
- }
-
- @Override
- public String getKnownHostsFile() {
- return myKnownHostsFile;
- }
-
- public void setKnownHostsFile(String knownHostsFile) {
- myKnownHostsFile = knownHostsFile;
- }
-
- @Override
- @Transient
- public String getPassphrase() {
- return myPassphrase;
- }
-
- public void setPassphrase(String passphrase) {
- myPassphrase = passphrase;
- }
-
- @Override
- public boolean isUseKeyPair() {
- return myUseKeyPair;
- }
-
- public void setUseKeyPair(boolean useKeyPair) {
- myUseKeyPair = useKeyPair;
- }
-
- public String getSerializedUserName() {
- if (myAnonymous || myUserName == null) return "";
- return myUserName;
- }
-
- public void setSerializedUserName(String userName) {
- if (StringUtil.isEmpty(userName)) {
- myUserName = null;
- }
- else {
- myUserName = userName;
- }
- }
-
- public String getSerializedPassword() {
- if (myAnonymous) return "";
-
- if (myStorePassword) {
- return PasswordUtil.encodePassword(myPassword);
- }
- else {
- return "";
- }
- }
-
- public void setSerializedPassword(String serializedPassword) {
- if (!StringUtil.isEmpty(serializedPassword)) {
- myPassword = PasswordUtil.decodePassword(serializedPassword);
- myStorePassword = true;
- }
- else {
- myPassword = null;
- }
- }
-
- @Nullable
- public String getSerializedPassphrase() {
- if (myStorePassphrase) {
- return PasswordUtil.encodePassword(myPassphrase);
- }
- else {
- return "";
- }
- }
-
- public void setSerializedPassphrase(String serializedPassphrase) {
- if (!StringUtil.isEmpty(serializedPassphrase)) {
- myPassphrase = PasswordUtil.decodePassword(serializedPassphrase);
- myStorePassphrase = true;
- }
- else {
- myPassphrase = null;
- myStorePassphrase = false;
- }
- }
-
- public void copyTo(RemoteSdkCredentials to) {
- to.setHost(getHost());
- to.setPort(getPort());
- to.setAnonymous(isAnonymous());
- to.setUserName(getUserName());
- to.setPassword(getPassword());
- to.setUseKeyPair(isUseKeyPair());
- to.setPrivateKeyFile(getPrivateKeyFile());
- to.setKnownHostsFile(getKnownHostsFile());
- to.setStorePassword(isStorePassword());
- to.setStorePassphrase(isStorePassphrase());
- }
+public class RemoteCredentialsHolder extends com.intellij.remote.RemoteCredentialsHolder {
}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteFile.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteFile.java
index 51896dbf1213..73274cc0f356 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteFile.java
+++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteFile.java
@@ -1,110 +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.remotesdk;
-import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
+ * @deprecated Remove in IDEA 14
+ *
* @author traff
*/
-public class RemoteFile {
-
- private final boolean myWin;
- private final String myPath;
+public class RemoteFile extends com.intellij.remote.RemoteFile {
public RemoteFile(@NotNull String path, boolean isWin) {
- myPath = toSystemDependent(path, isWin);
- myWin = isWin;
+ super(path, isWin);
}
public RemoteFile(@NotNull String parent, String child) {
- this(resolveChild(parent, child, isWindowsPath(parent)), isWindowsPath(parent));
+ super(parent, child);
}
public RemoteFile(@NotNull String parent, String child, boolean isWin) {
- this(resolveChild(parent, child, isWin), isWin);
- }
-
- @Nullable
- public String getName() {
- int ind = myPath.lastIndexOf(getSeparator(myWin));
- if (ind != -1 && ind < myPath.length() - 1) { //not last char
- return myPath.substring(ind + 1);
- }
- else {
- return null;
- }
- }
-
- private static String resolveChild(@NotNull String parent, @NotNull String child, boolean win) {
- String separator = getSeparator(win);
-
- String path;
- if (parent.endsWith(separator)) {
- path = parent + child;
- }
- else {
- path = parent + separator + child;
- }
- return path;
- }
-
- private static String getSeparator(boolean win) {
- String separator;
- if (win) {
- separator = "\\";
- }
- else {
- separator = "/";
- }
- return separator;
- }
-
-
- public String getPath() {
- return myPath;
- }
-
- public boolean isWin() {
- return isWindowsPath(myPath);
- }
-
- public static boolean isWindowsPath(@NotNull String path) {
- path = RemoteSdkCredentialsHolder.getInterpreterPathFromFullPath(path);
-
- return (path.length() > 1 && path.charAt(1) == ':');
- }
-
- private static String toSystemDependent(@NotNull String path, boolean isWin) {
- char separator = isWin ? '\\' : '/';
- return FileUtil.toSystemIndependentName(path).replace('/', separator);
- }
-
- public static RemoteFileBuilder detectSystemByPath(@NotNull String path) {
- return new RemoteFileBuilder(isWindowsPath(path));
- }
-
- public static RemoteFile createRemoteFile(String path, String script) {
- return detectSystemByPath(path).createRemoteFile(path, script);
- }
-
- public static RemoteFile createRemoteFile(final String path, final String script, final boolean isWindows) {
- return new RemoteFileBuilder(isWindows).createRemoteFile(path, script);
- }
-
- public static class RemoteFileBuilder {
- private final boolean isWin;
-
- private RemoteFileBuilder(boolean win) {
- isWin = win;
- }
-
- public RemoteFile createRemoteFile(String path) {
- return new RemoteFile(path, isWin);
- }
-
- public RemoteFile createRemoteFile(String path, String child) {
- return new RemoteFile(path, child, isWin);
- }
+ super(parent, child, isWin);
}
}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteInterpreterException.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteInterpreterException.java
index 0a31e6578cce..b3d3b35b5aa2 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteInterpreterException.java
+++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteInterpreterException.java
@@ -1,49 +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.remotesdk;
-import com.intellij.execution.ExecutionException;
-
-import java.net.NoRouteToHostException;
+import com.intellij.remote.RemoteSdkException;
/**
+ * @deprecated Remove in IDEA 14
+ *
* @author traff
*/
-public class RemoteInterpreterException extends ExecutionException {
- private final boolean myNoRouteToHost;
- private final boolean myAuthFailed;
-
+public class RemoteInterpreterException extends RemoteSdkException {
public RemoteInterpreterException(String s, Throwable throwable) {
super(s, throwable);
- myNoRouteToHost = throwable instanceof NoRouteToHostException;
- myAuthFailed = false;
- }
-
- public RemoteInterpreterException(String s) {
- super(s);
- myAuthFailed = false;
- myNoRouteToHost = false;
- }
-
- public boolean isNoRouteToHost() {
- return myNoRouteToHost;
- }
-
- public boolean isAuthFailed() {
- return myAuthFailed;
- }
-
- public String getMessage() {
- if (myNoRouteToHost) {
- return getCause().getMessage();
- }
- else if (myAuthFailed) {
- return "Authentication failed";
- }
- else {
- return super.getMessage();
- }
- }
-
- public static RemoteInterpreterException cantObtainRemoteCredentials(Throwable e) {
- return new RemoteInterpreterException("Cant obtain remote credentials", e);
}
}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteProcessHandlerBase.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteProcessHandlerBase.java
index c004f8ae211d..a83d2bdc2455 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteProcessHandlerBase.java
+++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteProcessHandlerBase.java
@@ -1,19 +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.remotesdk;
-import com.intellij.openapi.util.Pair;
-import com.intellij.util.PathMappingSettings;
-
-import java.util.List;
-
/**
+ * @deprecated Remove in IDEA 14
+ *
* @author traff
*/
-public interface RemoteProcessHandlerBase {
- PathMappingSettings getMappingSettings();
-
- Pair<String, Integer> obtainRemoteSocket() throws RemoteInterpreterException;
-
- void addRemoteForwarding(int remotePort, int localPort);
-
- List<PathMappingSettings.PathMapping> getFileMappings();
+public interface RemoteProcessHandlerBase extends com.intellij.remote.RemoteProcessHandlerBase {
}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkAdditionalData.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkAdditionalData.java
index d9f1b67bb836..e4c79ed8d7f2 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkAdditionalData.java
+++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkAdditionalData.java
@@ -1,8 +1,10 @@
package com.intellij.remotesdk;
import com.intellij.openapi.projectRoots.SdkAdditionalData;
+import com.intellij.remote.RemoteSdkCredentials;
/**
+ * @deprecated Remove in IDEA 14
* @author traff
*/
public interface RemoteSdkAdditionalData extends RemoteSdkCredentials, SdkAdditionalData {
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentials.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentials.java
deleted file mode 100644
index 11f14f05119d..000000000000
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentials.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.intellij.remotesdk;
-
-/**
- * @author traff
- */
-public interface RemoteSdkCredentials extends MutableRemoteCredentials, RemoteSdkProperties {
-}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkData.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkData.java
new file mode 100644
index 000000000000..d99ea338db00
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkData.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.remotesdk;
+
+import com.intellij.remote.RemoteSdkCredentials;
+
+/**
+ * @deprecated Remove in IDEA 14
+ *
+ * @author traff
+ */
+public interface RemoteSdkData extends RemoteSdkCredentials {
+}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataBuilder.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataBuilder.java
new file mode 100644
index 000000000000..f2dd26589392
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataBuilder.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.remotesdk;
+
+import com.intellij.remote.RemoteSdkCredentialsBuilder;
+
+/**
+ * @deprecated Remove in IDEA 14
+ *
+ * @author traff
+ */
+public class RemoteSdkDataBuilder extends RemoteSdkCredentialsBuilder {
+}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataHolder.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataHolder.java
new file mode 100644
index 000000000000..b4f837c72a3f
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataHolder.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.remotesdk;
+
+import com.intellij.remote.RemoteSdkCredentialsHolder;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @deprecated Remove in IDEA 14
+ *
+ * @author traff
+ */
+public class RemoteSdkDataHolder extends RemoteSdkCredentialsHolder {
+ public RemoteSdkDataHolder(@NotNull String defaultHelpersDirName) {
+ super(defaultHelpersDirName);
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkFactory.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkFactory.java
index 86113a5337bf..1934d1aa36a2 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkFactory.java
+++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkFactory.java
@@ -17,6 +17,7 @@ package com.intellij.remotesdk;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.remote.RemoteSdkException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -24,6 +25,7 @@ import java.awt.*;
import java.util.Collection;
/**
+ * @deprecated Remove in IDEA 14
* @author traff
*/
public interface RemoteSdkFactory<T extends RemoteSdkAdditionalData> {
diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java
index 35c589719b53..3abe39bd1aba 100644
--- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java
+++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java
@@ -1,22 +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.remotesdk;
-import com.intellij.execution.process.SelfKiller;
-
/**
+ * @deprecated Remove in IDEA 14
* @author traff
*/
-abstract public class RemoteSshProcess extends Process implements SelfKiller {
- /**
- * Makes host:localPort server which is available on local side available on remote side as localhost:remotePort.
- */
- public abstract void addRemoteTunnel(int remotePort, String host, int localPort) throws RemoteInterpreterException;
-
- /**
- * Makes host:remotePort server which is available on remote side available on local side as localhost:localPort.
- */
- public abstract void addLocalTunnel(int localPort, String host, int remotePort) throws RemoteInterpreterException;
-
- public abstract boolean hasPty();
-
- public abstract boolean sendCtrlC();
+public abstract class RemoteSshProcess extends com.intellij.remote.RemoteSshProcess {
}
diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
index c3ba3a3dd834..0070cb0a70e5 100644
--- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
+++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.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.
@@ -206,6 +206,7 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
if (!myEnabled) return;
if (selected == null
+ || !myComponent.isEnabled()
|| !myComponent.isShowing()
|| !myComponent.isFocusOwner() && !processIfUnfocused
|| isPopup()) {
diff --git a/platform/platform-impl/src/com/intellij/ui/FinderRecursivePanel.java b/platform/platform-impl/src/com/intellij/ui/FinderRecursivePanel.java
index 47970514f429..411186ce962d 100644
--- a/platform/platform-impl/src/com/intellij/ui/FinderRecursivePanel.java
+++ b/platform/platform-impl/src/com/intellij/ui/FinderRecursivePanel.java
@@ -7,6 +7,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.ide.CopyPasteManager;
+import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
@@ -423,7 +424,7 @@ public abstract class FinderRecursivePanel<T> extends JBSplitter implements Data
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
- ApplicationManager.getApplication().runReadAction(new Runnable() {
+ DumbService.getInstance(getProject()).runReadActionInSmartMode(new Runnable() {
@Override
public void run() {
try {
diff --git a/platform/platform-impl/src/com/intellij/ui/SystemNotifications.java b/platform/platform-impl/src/com/intellij/ui/SystemNotifications.java
index 08e38637801d..b0d7b371a3e0 100644
--- a/platform/platform-impl/src/com/intellij/ui/SystemNotifications.java
+++ b/platform/platform-impl/src/com/intellij/ui/SystemNotifications.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.ui;
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import org.jetbrains.annotations.NotNull;
@@ -22,8 +24,14 @@ import org.jetbrains.annotations.NotNull;
* @author mike
*/
public abstract class SystemNotifications {
+ private static final SystemNotifications NULL = new SystemNotifications() {
+ @Override
+ public void notify(@NotNull String notificationName, @NotNull String title, @NotNull String text) { }
+ };
+
public static SystemNotifications getInstance() {
- return ServiceManager.getService(SystemNotifications.class);
+ Application app = ApplicationManager.getApplication();
+ return app.isHeadlessEnvironment() || app.isUnitTestMode() ? NULL : ServiceManager.getService(SystemNotifications.class);
}
public abstract void notify(@NotNull String notificationName, @NotNull String title, @NotNull String text);
diff --git a/platform/platform-impl/src/com/intellij/ui/SystemNotificationsImpl.java b/platform/platform-impl/src/com/intellij/ui/SystemNotificationsImpl.java
index 597301bb1a2d..d81ea5846148 100644
--- a/platform/platform-impl/src/com/intellij/ui/SystemNotificationsImpl.java
+++ b/platform/platform-impl/src/com/intellij/ui/SystemNotificationsImpl.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.
@@ -83,7 +83,13 @@ public class SystemNotificationsImpl extends SystemNotifications implements Pers
}
}
catch (Throwable t) {
- Logger.getInstance(SystemNotifications.class).error(t);
+ Logger logger = Logger.getInstance(SystemNotifications.class);
+ if (logger.isDebugEnabled()) {
+ logger.debug(t);
+ }
+ else {
+ logger.info(t.getMessage());
+ }
}
return null;
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 aac44fcd37a2..1bee208832eb 100755
--- a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java
+++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java
@@ -20,13 +20,13 @@ import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.util.ui.UIUtil;
+import org.jdesktop.swingx.graphics.GraphicsUtilities;
+import org.jdesktop.swingx.graphics.ShadowRenderer;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
-import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
-import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
/**
@@ -45,9 +45,19 @@ public class SheetController {
private JButton[] buttons;
private JButton myDefaultButton;
private JButton myFocusedButton;
+
+ public int SHADOW_BORDER = 10;
+
+ // SHEET
public int SHEET_WIDTH = 400;
+
public int SHEET_HEIGHT = 150;
+ // SHEET + shadow
+ int SHEET_NC_WIDTH = SHEET_WIDTH + SHADOW_BORDER * 2;
+ int SHEET_NC_HEIGHT = SHEET_HEIGHT + SHADOW_BORDER ;
+
+
private Icon myIcon = AllIcons.Logo_welcomeScreen;
private String myResult;
@@ -151,9 +161,11 @@ public class SheetController {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.95f));
g2d.setColor(Gray._225);
- Rectangle2D dialog = new Rectangle2D.Double(0,0,mySheetPanel.getBounds().width - 5, mySheetPanel.getBounds().height - 10);
+ Rectangle2D dialog = new Rectangle2D.Double(SHADOW_BORDER, 0, SHEET_WIDTH, SHEET_HEIGHT);
+
+ paintShadow(g2d);
+ // draw the sheet background
g2d.fill(dialog);
- paintShadow(g2d, dialog);
}
};
@@ -211,21 +223,30 @@ public class SheetController {
SHEET_HEIGHT = 20 + headerLabel.getPreferredSize().height + 10 + messageArea.height + 10 + 70;
- sheetPanel.setSize(SHEET_WIDTH, SHEET_HEIGHT);
+
ico.setOpaque(false);
ico.setSize(new Dimension(AllIcons.Logo_welcomeScreen.getIconWidth(), AllIcons.Logo_welcomeScreen.getIconHeight()));
- ico.setLocation(20, 20);
+ ico.setLocation(40, 20);
sheetPanel.add(ico);
- headerLabel.setLocation(120, 20);
- messageTextPane.setLocation(120, 20 + headerLabel.getPreferredSize().height + 10);
+ headerLabel.setLocation(140, 20);
+ messageTextPane.setLocation(140, 20 + headerLabel.getPreferredSize().height + 10);
layoutWithAbsoluteLayout(buttons, sheetPanel);
sheetPanel.setFocusCycleRoot(true);
+ recalculateShadow();
+
+ sheetPanel.setSize(SHEET_NC_WIDTH, SHEET_NC_HEIGHT );
+
return sheetPanel;
}
+ private void recalculateShadow() {
+ SHEET_NC_WIDTH = SHEET_WIDTH + SHADOW_BORDER * 2;
+ SHEET_NC_HEIGHT = SHEET_HEIGHT + SHADOW_BORDER;
+ }
+
private void layoutWithAbsoluteLayout(JButton[] buttons, JPanel sheetPanel) {
layoutButtons(buttons, sheetPanel);
@@ -235,31 +256,33 @@ public class SheetController {
}
}
- private void paintShadow(Graphics2D g2d, Rectangle2D dialog) {
- Area shadow = new Area(new RoundRectangle2D.Double(0, 0, mySheetPanel.getBounds().width, mySheetPanel.getBounds().height, 10, 10));
-
- g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.80f));
-
- Color color1 = Gray._130;
- Color color2 = new JBColor(new Color(130, 130, 130, 0), new Color(130, 130, 130, 0));
-
- GradientPaint gp = new GradientPaint(
- 0, mySheetPanel.getBounds().height - 10, color1,
- 0, mySheetPanel.getBounds().height, color2 );
-
- g2d.setPaint(gp);
- shadow.subtract(new Area(dialog));
- g2d.fill(shadow);
+ private void paintShadow(Graphics2D g2d) {
+ BufferedImage bufferedImage = GraphicsUtilities.createCompatibleTranslucentImage(
+ SHEET_WIDTH, SHEET_HEIGHT);
+
+ Graphics2D g2 = bufferedImage.createGraphics();
+ g2.setColor(JBColor.WHITE);
+ g2.fillRoundRect(0, 0, SHEET_WIDTH - 1, SHEET_HEIGHT - 1, SHADOW_BORDER, SHADOW_BORDER);
+ g2.dispose();
+
+ ShadowRenderer renderer = new ShadowRenderer();
+ renderer.setSize(SHADOW_BORDER);
+ renderer.setOpacity(0.95f);
+ renderer.setColor(JBColor.BLACK);
+ BufferedImage shadow = renderer.createShadow(bufferedImage);
+ g2d.drawImage(shadow, 0, - SHADOW_BORDER, null);
+ g2d.setBackground(new JBColor(new Color(255, 255, 255, 0), new Color(255, 255, 255, 0)));
+ g2d.clearRect(SHADOW_BORDER, 0, SHEET_WIDTH, SHEET_HEIGHT);
}
private void layoutButtons(final JButton[] buttons, JPanel panel) {
- int buttonsWidth = 120;
+ int buttonsWidth = 15 * 2;
for (JButton button : buttons) {
panel.add(button);
button.repaint();
- buttonsWidth = button.getWidth() + 10;
+ buttonsWidth += button.getPreferredSize().width + 10;
}
SHEET_WIDTH = Math.max(buttonsWidth, SHEET_WIDTH);
@@ -298,7 +321,7 @@ public class SheetController {
myOffScreenFrame.add(mySheetPanel);
myOffScreenFrame.getRootPane().setDefaultButton(myDefaultButton);
- final BufferedImage image = UIUtil.createImage(SHEET_WIDTH, SHEET_HEIGHT, BufferedImage.TYPE_INT_ARGB);
+ final BufferedImage image = UIUtil.createImage(SHEET_NC_WIDTH, SHEET_NC_HEIGHT, BufferedImage.TYPE_INT_ARGB);
mySheetPanel.paint(image.createGraphics());
myOffScreenFrame.dispose();
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 e90078aa7a19..f2249ad89e12 100755
--- a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java
+++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java
@@ -54,13 +54,14 @@ public class SheetMessage {
@Override
public void paint(Graphics g) {
super.paint(g);
+
}
};
myParent = owner;
myWindow.setUndecorated(true);
- myWindow.setBackground(new JBColor(new Color(0, 0, 0, 0), new Color(0, 0, 0, 0)));
+ myWindow.setBackground(new JBColor(new Color(0, 0, 0, 0), new Color(0, 0, 0, 0)));
myController = new SheetController(this, title, message, icon, buttons, defaultButton, doNotAskOption, focusedButton);
@@ -70,7 +71,7 @@ public class SheetMessage {
myWindow.setFocusable(true);
startAnimation(true);
- myWindow.setSize(myController.SHEET_WIDTH, myController.SHEET_HEIGHT);
+ myWindow.setSize(myController.SHEET_NC_WIDTH, myController.SHEET_NC_HEIGHT);
restoreFullscreenButton = couldBeInFullScreen();
if (restoreFullscreenButton) {
FullScreenUtilities.setWindowCanFullScreen(myParent, false);
@@ -108,24 +109,24 @@ public class SheetMessage {
int imageCropOffset = (UIUtil.isRetina()) ? imageHeight * 2 : imageHeight;
- g.drawImage(staticImage, 0,0,myController.SHEET_WIDTH,imageHeight,
+ g.drawImage(staticImage, 0, 0, myController.SHEET_NC_WIDTH,imageHeight,
0, staticImage.getHeight(null) - imageCropOffset,
staticImage.getWidth(null) ,staticImage.getHeight(null) ,null);
}
}
};
staticPanel.setOpaque(false);
- staticPanel.setSize(myController.SHEET_WIDTH,myController.SHEET_HEIGHT);
+ staticPanel.setSize(myController.SHEET_NC_WIDTH,myController.SHEET_NC_HEIGHT);
myWindow.setContentPane(staticPanel);
- Animator myAnimator = new Animator("Roll Down Sheet Animator", myController.SHEET_HEIGHT ,
+ Animator myAnimator = new Animator("Roll Down Sheet Animator", myController.SHEET_NC_HEIGHT ,
TIME_TO_SHOW_SHEET, false) {
@Override
public void paintNow(int frame, int totalFrames, int cycle) {
setPositionRelativeToParent();
float percentage = (float)frame/(float)totalFrames;
- imageHeight = enlarge ? (int)(((float)myController.SHEET_HEIGHT) * percentage):
- (int)(myController.SHEET_HEIGHT - percentage * myController.SHEET_HEIGHT);
+ imageHeight = enlarge ? (int)(((float)myController.SHEET_NC_HEIGHT) * percentage):
+ (int)(myController.SHEET_NC_HEIGHT - percentage * myController.SHEET_HEIGHT);
myWindow.repaint();
}
@@ -133,9 +134,10 @@ public class SheetMessage {
protected void paintCycleEnd() {
setPositionRelativeToParent();
if (enlarge) {
- imageHeight = myController.SHEET_HEIGHT;
+ imageHeight = myController.SHEET_NC_HEIGHT;
staticImage = null;
myWindow.setContentPane(myController.getPanel(myWindow));
+
myController.requestFocus();
} else {
if (restoreFullscreenButton) {
@@ -152,8 +154,11 @@ public class SheetMessage {
private void setPositionRelativeToParent () {
int width = myParent.getWidth();
- myWindow.setLocation(width / 2 - myController.SHEET_WIDTH / 2 + myParent.getLocation().x,
- myParent.getInsets().top + myParent.getLocation().y);
+ myWindow.setBounds(width / 2 - myController.SHEET_NC_WIDTH / 2 + myParent.getLocation().x,
+ myParent.getInsets().top + myParent.getLocation().y,
+ myController.SHEET_NC_WIDTH,
+ myController.SHEET_NC_HEIGHT);
+
}
private void registerMoveResizeHandler () {
diff --git a/platform/platform-impl/src/org/jetbrains/ide/BuiltInServerManagerImpl.java b/platform/platform-impl/src/org/jetbrains/ide/BuiltInServerManagerImpl.java
index cf1104a405a2..51ebd5ef5c0c 100644
--- a/platform/platform-impl/src/org/jetbrains/ide/BuiltInServerManagerImpl.java
+++ b/platform/platform-impl/src/org/jetbrains/ide/BuiltInServerManagerImpl.java
@@ -20,6 +20,8 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.io.BuiltInServer;
+import java.util.Random;
+import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -39,11 +41,12 @@ public class BuiltInServerManagerImpl extends BuiltInServerManager {
private BuiltInServer server;
private boolean enabledInUnitTestMode = true;
- //static {
- // // IDEA-120811
- // System.setProperty("io.netty.machineId", Integer.toHexString(new Random().nextInt()));
- // System.setProperty("io.netty.processId", "1");
- //}
+ static {
+ // IDEA-120811
+ String id = UUID.randomUUID().toString();
+ System.setProperty("io.netty.machineId", id.substring(id.length() - 8));
+ System.setProperty("io.netty.processId", Integer.toString(new Random().nextInt(65535)));
+ }
@Override
public int getPort() {
diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties
index 8d51e6b5dbd2..79c6129ca776 100644
--- a/platform/platform-resources-en/src/messages/ActionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties
@@ -107,8 +107,9 @@ action.EditorMoveUpAndScrollWithSelection.text=Move Up and Scroll with Selection
action.EditorMoveDownAndScrollWithSelection.text=Move Down and Scroll with Selection
action.EditorCloneCaretBelow.text=Clone Caret Below
action.EditorCloneCaretAbove.text=Clone Caret Above
-action.SelectNextOccurence.text=Select Next Occurence
-action.UnselectLastOccurence.text=Unselect Last Occurence
+action.SelectNextOccurrence.text=Select Next Occurrence
+action.SelectAllOccurrences.text=Select All Occurrences
+action.UnselectPreviousOccurrence.text=Unselect Occurrence
action.EditorToggleStickySelection.text=Toggle Sticky Selection
action.EditorSwapSelectionBoundaries.text=Swap selection boundaries
action.EditorLineStart.text=Move Caret to Line Start
@@ -910,7 +911,10 @@ action.XDebugger.JumpToSource.description=Open source of the selected item
action.XDebugger.JumpToTypeSource.text=Jump To Type Source
action.XDebugger.JumpToTypeSource.description=Open source of the selected value's type
action.XDebugger.Inspect.text=Inspect...
-action.XDebugger.AddToWatches.text=Add to Watches
+
+action.Debugger.Tree.AddToWatches.text=Add to Watches
+action.Debugger.Tree.EvaluateInConsole.text=Evaluate In Console
+
action.XDebugger.RemoveWatch.text=Remove Watch
action.XDebugger.RemoveAllWatches.text=Remove All Watches
action.XDebugger.NewWatch.text=New Watch...
@@ -949,6 +953,7 @@ action.Debugger.MarkObject.text=Mark Object...
action.Debugger.MarkObject.unmark.text=Unmark Object
action.Debugger.MarkObject.description=Mark/unmark the object so that it can be visually distinguished in in debugger views
action.Debugger.AddToWatch.text=Add to Watches
+action.Debugger.EvaluateInConsole.text=Evaluate in Console
action.Debugger.AutoRenderer.text=Auto
group.EditorPopupMenu.text=Editor Popup Menu
group.EditorPopupMenu.description=Editor Popup Menu
diff --git a/platform/platform-resources-en/src/messages/DiffBundle.properties b/platform/platform-resources-en/src/messages/DiffBundle.properties
index 66a7bab05489..096fa117e2c8 100644
--- a/platform/platform-resources-en/src/messages/DiffBundle.properties
+++ b/platform/platform-resources-en/src/messages/DiffBundle.properties
@@ -32,7 +32,7 @@ diff.acton.ignore.whitespace.policy.do.not.ignore=Do not ignore
diff.acton.ignore.whitespace.policy.leading.and.trailing=Leading and trailing
diff.acton.ignore.whitespace.policy.all=All
ignore.whitespace.acton.name=Ignore whitespace:
-ignore.whitespace.action.not.available.action.name=<Not available>
+diff.panel.combo.box.action.not.available.action.name=<Not available>
diff.dialog.select.change.action.name=Select Change
diff.dialog.select.change.action.description=Select changed text in this version and corresponding in other
merge.files.dialog.title=Merge
@@ -85,8 +85,7 @@ diff.content.selected.value=Selected Value
diff.clipboard.vs.value.dialog.title=Clipboard vs Selected Value
diff.can.not.show.unknown=Can not show diff for unknown file type
-diff.acton.highlight.mode.action.by.word=By Word
-diff.acton.highlight.mode.action.by.line=By Line
-diff.acton.highlight.mode.action.no.highlighting=No Highlighting
-diff.acton.highlight.mode.not.available.action.name=<Not available>
-diff.acton.highlight.mode.action.name=Highlighting Mode:
+diff.acton.highlight.mode.action.by.word=By word
+diff.acton.highlight.mode.action.by.line=By line
+diff.acton.highlight.mode.action.no.highlighting=Do not highlight
+diff.acton.highlight.mode.action.name=Highlight:
diff --git a/platform/platform-resources-en/src/messages/FindBundle.properties b/platform/platform-resources-en/src/messages/FindBundle.properties
index 26959ba14d4b..2c17b13d459d 100644
--- a/platform/platform-resources-en/src/messages/FindBundle.properties
+++ b/platform/platform-resources-en/src/messages/FindBundle.properties
@@ -76,7 +76,7 @@ find.empty.match.regular.expression.error=Regular expression matches empty strin
find.filter.invalid.file.mask.error=Bad file mask \"{0}\"
find.filter.empty.file.mask.error=Empty file mask
find.options.case.sensitive=&Case sensitive
-find.options.replace.preserve.case=Preser&ve case
+find.options.replace.preserve.case=&Preserve case
find.options.whole.words.only=Whole wo&rds only (may be faster)
find.options.string.literals.only=S&tring literals only
find.options.comments.only=Comm&ents only
@@ -85,7 +85,7 @@ find.direction.group=Direction
find.direction.forward.radio=F&orward
find.direction.backward.radio=&Backward
find.scope.group=Scope
-find.scope.whole.project.radio=Whole &project
+find.scope.whole.project.radio=W&hole project
find.scope.all.projects.radio=All &projects
find.scope.module.radio=&Module:
find.scope.project.radio=Pro&ject
diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties
index b61965b67b3d..c1567482dc41 100644
--- a/platform/platform-resources-en/src/misc/registry.properties
+++ b/platform/platform-resources-en/src/misc/registry.properties
@@ -321,7 +321,6 @@ ui.no.bangs.and.whistles=false
comment.by.line.bulk.lines.trigger=100
-scene.builder.start.executable=true
junit_sm_runner=false
testng_sm_runner=false
show.flex.debug.design.view=false
@@ -365,7 +364,7 @@ ide.open.file.in.temp.project.dir=true
ide.open.file.in.temp.project.dir.description=Enables opening file in temp project directory
editor.allow.multiple.carets=false
-embed.scene.builder=false
+embed.scene.builder=true
dsm.retina.darcula.legend=true
dsm.retina.darcula.legend.description=Experimental DSM legend component
diff --git a/platform/platform-resources/src/DefaultColorSchemesManager.xml b/platform/platform-resources/src/DefaultColorSchemesManager.xml
index d43993b72313..b3f6d7f21226 100644
--- a/platform/platform-resources/src/DefaultColorSchemesManager.xml
+++ b/platform/platform-resources/src/DefaultColorSchemesManager.xml
@@ -416,20 +416,6 @@
<option name="EFFECT_COLOR"/>
</value>
</option>
- <option name="REASSIGNED_LOCAL_VARIABLE_ATTRIBUTES">
- <value>
- <option name="FOREGROUND"/>
- <option name="BACKGROUND"/>
- <option name="EFFECT_COLOR"/>
- </value>
- </option>
- <option name="REASSIGNED_PARAMETER_ATTRIBUTES">
- <value>
- <option name="FOREGROUND"/>
- <option name="BACKGROUND"/>
- <option name="EFFECT_COLOR"/>
- </value>
- </option>
<option name="IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES">
<value>
<option name="FOREGROUND" value="660e7a"/>
diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml
index c554cf36ff7c..62fe04251a31 100644
--- a/platform/platform-resources/src/META-INF/LangExtensions.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensions.xml
@@ -343,6 +343,9 @@
<projectService serviceInterface="com.intellij.openapi.roots.impl.LibraryScopeCache"
serviceImplementation="com.intellij.openapi.roots.impl.LibraryScopeCache"/>
+ <projectService serviceInterface="com.intellij.ide.scratch.ScratchpadManager"
+ serviceImplementation="com.intellij.ide.scratch.ScratchpadManagerImpl"/>
+
<colorSettingsPage implementation="com.intellij.openapi.options.colors.pages.GeneralColorsPage" id="general"/>
<colorSettingsPage implementation="com.intellij.openapi.options.colors.pages.DefaultLanguageColorsPage" id="defaultLanguage"/>
<colorSettingsPage implementation="com.intellij.openapi.options.colors.pages.ANSIColoredConsoleColorsPage" id="ansi"/>
@@ -875,6 +878,8 @@
<stepsBeforeRunProvider implementation="com.intellij.execution.impl.RunConfigurationBeforeRunProvider"/>
<lang.foldingBuilder language="TEXT" implementationClass="com.intellij.ide.highlighter.custom.impl.CustomFileTypeFoldingBuilder"/>
+
+ <virtualFileSystem key="scratchpad" implementationClass="com.intellij.ide.scratch.ScratchpadFileSystem"/>
</extensions>
</idea-plugin>
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
index 854e1ce08535..b6189cf69a47 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
@@ -190,6 +190,8 @@
<projectService serviceInterface="com.intellij.openapi.vcs.VcsFileListenerContextHelper"
serviceImplementation="com.intellij.openapi.vcs.VcsFileListenerContextHelper"/>
+ <projectService serviceImplementation="com.intellij.openapi.editor.LazyRangeMarkerFactory"/>
+
<!-- General -->
<applicationConfigurable instance="com.intellij.ide.GeneralSettingsConfigurable"/>
diff --git a/platform/platform-resources/src/brokenPlugins.txt b/platform/platform-resources/src/brokenPlugins.txt
index e34b74e756ab..a6d760367b5d 100644
--- a/platform/platform-resources/src/brokenPlugins.txt
+++ b/platform/platform-resources/src/brokenPlugins.txt
@@ -9,7 +9,8 @@ com.jetbrains.twig 133.51 130.1639
org.jetbrains.plugins.ruby 6.0.0.20140207
Pythonid 3.1
Karma 134.1163 134.1039 134.686 134.31
-org.intellij.scala 0.32.512
+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
SBT 1.0.0 1.1.0 1.2.0 1.3.0 1.3.1 1.4.0 1.5.0
-"JSTestDriver Plugin" 134.1163 134.686 134.31 134.307 134.1039 \ No newline at end of file
+"JSTestDriver Plugin" 134.1163 134.686 134.31 134.307 134.1039
+AngularJS 134.1094 0.1.8 0.1.9 \ No newline at end of file
diff --git a/platform/platform-resources/src/componentSets/Editor.xml b/platform/platform-resources/src/componentSets/Editor.xml
index adf1f3bf5d7f..25719abb23f3 100644
--- a/platform/platform-resources/src/componentSets/Editor.xml
+++ b/platform/platform-resources/src/componentSets/Editor.xml
@@ -30,9 +30,5 @@
<interface-class>com.intellij.openapi.fileEditor.ex.IdeDocumentHistory</interface-class>
<implementation-class>com.intellij.openapi.fileEditor.impl.IdeDocumentHistoryImpl</implementation-class>
</component>
- <component>
- <implementation-class>com.intellij.openapi.editor.LazyRangeMarkerFactory</implementation-class>
- <loadForDefaultProject/>
- </component>
</project-components>
</components> \ No newline at end of file
diff --git a/platform/platform-resources/src/idea/Keymap_Default.xml b/platform/platform-resources/src/idea/Keymap_Default.xml
index 447d4abfb649..c7135845bb32 100644
--- a/platform/platform-resources/src/idea/Keymap_Default.xml
+++ b/platform/platform-resources/src/idea/Keymap_Default.xml
@@ -115,7 +115,7 @@
<action id="SelectNextOccurrence">
<keyboard-shortcut first-keystroke="alt J"/>
</action>
- <action id="UnselectLastOccurrence">
+ <action id="UnselectPreviousOccurrence">
<keyboard-shortcut first-keystroke="alt shift J"/>
</action>
<action id="GotoDeclaration">
@@ -958,5 +958,9 @@
<action id ="Refactorings.QuickListPopupAction">
<keyboard-shortcut first-keystroke="control alt shift T"/>
</action>
+
+ <action id="NewScratchFile">
+ <keyboard-shortcut first-keystroke="control alt shift INSERT"/>
+ </action>
</keymap>
</component>
diff --git a/platform/platform-resources/src/idea/Keymap_Eclipse.xml b/platform/platform-resources/src/idea/Keymap_Eclipse.xml
index 2a28414bd583..ecc3b0488e6b 100644
--- a/platform/platform-resources/src/idea/Keymap_Eclipse.xml
+++ b/platform/platform-resources/src/idea/Keymap_Eclipse.xml
@@ -121,10 +121,13 @@
<action id="FindPrevious">
<keyboard-shortcut first-keystroke="shift control K" />
</action>
+ <action id="SelectAllOccurrences">
+ <keyboard-shortcut first-keystroke="alt control Y"/>
+ </action>
<action id="SelectNextOccurrence">
<keyboard-shortcut first-keystroke="alt Y"/>
</action>
- <action id="UnselectLastOccurrence">
+ <action id="UnselectPreviousOccurrence">
<keyboard-shortcut first-keystroke="alt shift Y"/>
</action>
<action id="FindUsages">
diff --git a/platform/platform-resources/src/idea/Keymap_Mac.xml b/platform/platform-resources/src/idea/Keymap_Mac.xml
index 42cf466cd85b..32dd27f12dfe 100644
--- a/platform/platform-resources/src/idea/Keymap_Mac.xml
+++ b/platform/platform-resources/src/idea/Keymap_Mac.xml
@@ -349,6 +349,16 @@
<action id="FindPrevious">
<keyboard-shortcut first-keystroke="meta shift G"/>
</action>
+
+ <action id="SelectNextOccurrence">
+ <keyboard-shortcut first-keystroke="control G"/>
+ </action>
+ <action id="UnselectPreviousOccurrence">
+ <keyboard-shortcut first-keystroke="control shift G"/>
+ </action>
+ <action id="SelectAllOccurrences">
+ <keyboard-shortcut first-keystroke="meta control G"/>
+ </action>
<action id="Run">
<keyboard-shortcut first-keystroke="control R"/>
@@ -538,5 +548,9 @@
<action id ="Refactorings.QuickListPopupAction">
<keyboard-shortcut first-keystroke="control T"/>
</action>
+
+ <action id="NewScratchFile">
+ <keyboard-shortcut first-keystroke="meta shift N"/>
+ </action>
</keymap>
</component>
diff --git a/platform/platform-resources/src/idea/Keymap_MacClassic.xml b/platform/platform-resources/src/idea/Keymap_MacClassic.xml
index 1ce8e72fa7bc..532ac8983908 100644
--- a/platform/platform-resources/src/idea/Keymap_MacClassic.xml
+++ b/platform/platform-resources/src/idea/Keymap_MacClassic.xml
@@ -258,6 +258,16 @@
<keyboard-shortcut first-keystroke="shift F3"/>
<keyboard-shortcut first-keystroke="control shift L"/>
</action>
+
+ <action id="SelectNextOccurrence">
+ <keyboard-shortcut first-keystroke="control G"/>
+ </action>
+ <action id="UnselectPreviousOccurrence">
+ <keyboard-shortcut first-keystroke="control shift G"/>
+ </action>
+ <action id="SelectAllOccurrences">
+ <keyboard-shortcut first-keystroke="meta control G"/>
+ </action>
<action id="VcsShowNextChangeMarker">
<keyboard-shortcut first-keystroke="shift control alt DOWN"/>
diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml
index bdaf6c857512..3b8798230323 100644
--- a/platform/platform-resources/src/idea/LangActions.xml
+++ b/platform/platform-resources/src/idea/LangActions.xml
@@ -319,6 +319,10 @@
<add-to-group group-id="ToolsMenu" anchor="last"/>
</group>
+ <action id="NewScratchFile" class="com.intellij.ide.scratch.CreateScratchFileAction">
+ <add-to-group group-id="ToolsBasicGroup" anchor="first"/>
+ </action>
+
<group id="NewGroup" popup="true">
<action id="NewFile" class="com.intellij.ide.actions.CreateFileAction"/>
<action id="NewDir" class="com.intellij.ide.actions.CreateDirectoryOrPackageAction"/>
@@ -641,6 +645,7 @@
</group>
<action id="Debugger.AddToWatch" class="com.intellij.xdebugger.impl.actions.AddToWatchesAction" icon="AllIcons.Debugger.AddToWatch"/>
+ <action id="Debugger.EvaluateInConsole" class="com.intellij.xdebugger.impl.actions.EvaluateInConsoleAction"/>
<group id="EditorPopupMenuDebug">
<separator/>
@@ -648,6 +653,7 @@
<reference ref="RunToCursor"/>
<reference ref="ForceRunToCursor"/>
<reference ref="Debugger.AddToWatch"/>
+ <reference ref="Debugger.EvaluateInConsole"/>
<separator/>
<add-to-group group-id="EditorLangPopupMenu" relative-to-action="EditorPopupMenu.Run" anchor="before"/>
@@ -662,7 +668,10 @@
<action id="XDebugger.Inspect" class="com.intellij.xdebugger.impl.ui.tree.actions.XInspectAction"/>
<action id="XDebugger.JumpToSource" class="com.intellij.xdebugger.impl.ui.tree.actions.XJumpToSourceAction"/>
<action id="XDebugger.JumpToTypeSource" class="com.intellij.xdebugger.impl.ui.tree.actions.XJumpToTypeSourceAction"/>
- <action id="XDebugger.AddToWatches" class="com.intellij.xdebugger.impl.ui.tree.actions.XAddToWatchesAction" icon="AllIcons.Debugger.AddToWatch"/>
+
+ <action id="Debugger.Tree.AddToWatches" class="com.intellij.xdebugger.impl.ui.tree.actions.XAddToWatchesAction" icon="AllIcons.Debugger.AddToWatch"/>
+ <action id="Debugger.Tree.EvaluateInConsole" class="com.intellij.xdebugger.impl.ui.tree.actions.EvaluateInConsoleFromTreeAction"/>
+
<action id="XDebugger.NewWatch" class="com.intellij.xdebugger.impl.frame.actions.XNewWatchAction" icon="AllIcons.Debugger.NewWatch"/>
<action id="XDebugger.EditWatch" class="com.intellij.xdebugger.impl.frame.actions.XEditWatchAction"/>
<action id="XDebugger.RemoveWatch" class="com.intellij.xdebugger.impl.frame.actions.XRemoveWatchAction" icon="AllIcons.Actions.Delete"/>
@@ -712,7 +721,8 @@
<reference ref="XDebugger.ValueGroup"/>
<reference ref="XDebugger.JumpToSource"/>
<reference ref="XDebugger.JumpToTypeSource"/>
- <reference ref="XDebugger.AddToWatches"/>
+ <reference ref="Debugger.Tree.AddToWatches"/>
+ <reference ref="Debugger.Tree.EvaluateInConsole"/>
</group>
<group id="XDebugger.Variables.Tree.Toolbar">
@@ -733,7 +743,8 @@
<group id="XDebugger.Inspect.Tree.Popup">
<reference ref="XDebugger.ValueGroup"/>
- <reference ref="XDebugger.AddToWatches"/>
+ <reference ref="Debugger.Tree.AddToWatches"/>
+ <reference ref="Debugger.Tree.EvaluateInConsole"/>
</group>
<group id="XDebugger.Settings" icon="AllIcons.General.SecondaryGroup" popup="true">
diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml
index e0e136024f2a..5d2d399712d7 100644
--- a/platform/platform-resources/src/idea/PlatformActions.xml
+++ b/platform/platform-resources/src/idea/PlatformActions.xml
@@ -225,8 +225,9 @@
<action id="FindNext" class="com.intellij.ide.actions.SearchAgainAction"/>
<action id="FindPrevious" class="com.intellij.ide.actions.SearchBackAction"/>
<action id="FindWordAtCaret" class="com.intellij.openapi.editor.actions.FindWordAtCaretAction"/>
+ <action id="SelectAllOccurrences" class="com.intellij.openapi.editor.actions.SelectAllOccurrencesAction"/>
<action id="SelectNextOccurrence" class="com.intellij.openapi.editor.actions.SelectNextOccurrenceAction"/>
- <action id="UnselectLastOccurrence" class="com.intellij.openapi.editor.actions.UnselectLastOccurrenceAction"/>
+ <action id="UnselectPreviousOccurrence" class="com.intellij.openapi.editor.actions.UnselectPreviousOccurrenceAction"/>
<separator/>
<action id="FindInPath" class="com.intellij.find.actions.FindInPathAction"/>
<action id="ReplaceInPath" class="com.intellij.find.actions.ReplaceInPathAction"/>
diff --git a/platform/platform-tests/platform-tests.iml b/platform/platform-tests/platform-tests.iml
index d1018688da69..f6d37e431c5e 100644
--- a/platform/platform-tests/platform-tests.iml
+++ b/platform/platform-tests/platform-tests.iml
@@ -23,6 +23,7 @@
<orderEntry type="library" name="Groovy" level="project" />
<orderEntry type="library" name="Netty" level="project" />
<orderEntry type="library" name="http-client" level="project" />
+ <orderEntry type="module" module-name="jps-model-impl" scope="TEST" />
</component>
</module>
diff --git a/platform/platform-tests/testSrc/com/intellij/history/integration/TestVirtualFile.java b/platform/platform-tests/testSrc/com/intellij/history/integration/TestVirtualFile.java
index 990291816e30..44473dfdfe64 100644
--- a/platform/platform-tests/testSrc/com/intellij/history/integration/TestVirtualFile.java
+++ b/platform/platform-tests/testSrc/com/intellij/history/integration/TestVirtualFile.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.
@@ -33,12 +33,12 @@ import java.util.List;
// todo get rid of!!!!!!!!!!!!!
public class TestVirtualFile extends VirtualFile {
- private String myName;
+ private final String myName;
private String myContent;
private boolean isReadOnly;
private long myTimestamp;
- private boolean IsDirectory;
+ private final boolean IsDirectory;
private VirtualFile myParent;
private final List<TestVirtualFile> myChildren = new ArrayList<TestVirtualFile>();
@@ -76,6 +76,7 @@ public class TestVirtualFile extends VirtualFile {
return IsDirectory;
}
+ @NotNull
@Override
public String getPath() {
if (myParent == null) return myName;
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/IgnoreWhiteSpaceTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/IgnoreWhiteSpaceTest.java
index 7eb6c45e6b4f..de5a6ba61b2b 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/IgnoreWhiteSpaceTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/IgnoreWhiteSpaceTest.java
@@ -31,4 +31,13 @@ public class IgnoreWhiteSpaceTest extends TestCase {
assertEquals(keys[1], keys[2]);
assertFalse(keys[2].equals(keys[3]));
}
+
+ public static void assertEquals(Object obj1, Object obj2) {
+ if (obj1 instanceof CharSequence && obj2 instanceof CharSequence) {
+ assertEquals(obj1.toString(), obj2.toString());
+ return;
+ }
+
+ assertEquals(obj1, obj2);
+ }
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/highlighting/UtilTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/highlighting/UtilTest.java
index db929203a68a..1d19fb92ee44 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/highlighting/UtilTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/highlighting/UtilTest.java
@@ -2,6 +2,7 @@ package com.intellij.openapi.diff.impl.highlighting;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.MultiCheck;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.util.Assertion;
import com.intellij.util.diff.Diff;
import com.intellij.util.diff.FilesTooBigForDiffException;
@@ -209,10 +210,11 @@ public class UtilTest extends TestCase {
last};
lines = Util.uniteFormattingOnly(lines);
CHECK.compareAll(new DiffFragment[][]{
- first,
- new DiffFragment[]{inline1, inline2, inline3, inline4},
- last},
- lines);
+ first,
+ new DiffFragment[]{inline1, inline2, inline3, inline4},
+ last},
+ lines
+ );
}
public void testConcatenateEquals() {
@@ -246,7 +248,8 @@ public class UtilTest extends TestCase {
CHECK.singleElement(Util.cutFirst(new DiffFragment[]{
DiffFragment.unchanged("ab", "ac")
}),
- DiffFragment.unchanged("b", "c"));
+ DiffFragment.unchanged("b", "c")
+ );
CHECK.compareAll(new DiffFragment[]{
new DiffFragment(null, "c")
@@ -264,7 +267,8 @@ public class UtilTest extends TestCase {
Util.cutFirst(new DiffFragment[]{
new DiffFragment(null, "ab"),
new DiffFragment("c", "d")
- }));
+ })
+ );
}
public void testCutFirst2() {
@@ -293,4 +297,8 @@ public class UtilTest extends TestCase {
}));
}
+
+ public static void assertEquals(CharSequence obj1, CharSequence obj2) {
+ assertEquals(obj1.toString(), obj2.toString());
+ }
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/processing/LineBlocksDiffPolicyTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/processing/LineBlocksDiffPolicyTest.java
index badcc338a445..2baf119ba240 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/processing/LineBlocksDiffPolicyTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/processing/LineBlocksDiffPolicyTest.java
@@ -5,7 +5,6 @@ import com.intellij.openapi.diff.impl.ComparisonPolicy;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
import com.intellij.openapi.diff.impl.highlighting.Util;
import com.intellij.util.diff.FilesTooBigForDiffException;
-import junit.framework.Assert;
import junit.framework.TestCase;
public class LineBlocksDiffPolicyTest extends TestCase{
@@ -16,9 +15,9 @@ public class LineBlocksDiffPolicyTest extends TestCase{
checkPolicy(diffPolicy, "abc\n123\n", "ABC\nXYZ");
}
- private void checkPolicy(DiffPolicy.LineBlocks diffPolicy, String text1, String text2) throws FilesTooBigForDiffException {
+ private static void checkPolicy(DiffPolicy.LineBlocks diffPolicy, String text1, String text2) throws FilesTooBigForDiffException {
DiffFragment[] fragments = diffPolicy.buildFragments(text1, text2);
- Assert.assertEquals(text1, Util.getText(fragments, FragmentSide.SIDE1));
- assertEquals(text2, Util.getText(fragments, FragmentSide.SIDE2));
+ assertEquals(text1, Util.getText(fragments, FragmentSide.SIDE1).toString());
+ assertEquals(text2, Util.getText(fragments, FragmentSide.SIDE2).toString());
}
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/processing/TextCompareProcessorTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/processing/TextCompareProcessorTest.java
index 4d4ed9b9937f..854a17d47ebd 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/processing/TextCompareProcessorTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/diff/impl/processing/TextCompareProcessorTest.java
@@ -5,12 +5,12 @@ import com.intellij.openapi.diff.impl.fragments.LineFragment;
import com.intellij.util.diff.FilesTooBigForDiffException;
import junit.framework.TestCase;
-import java.util.ArrayList;
+import java.util.List;
public class TextCompareProcessorTest extends TestCase {
public void testIgnoreWrappingEqualText() throws FilesTooBigForDiffException {
TextCompareProcessor processor = new TextCompareProcessor(ComparisonPolicy.IGNORE_SPACE);
- ArrayList<LineFragment> lineFragments = processor.process("f(a, b)\n", "f(a,\nb)\n");
+ List<LineFragment> lineFragments = processor.process("f(a, b)\n", "f(a,\nb)\n");
assertTrue(lineFragments.size() == 1);
assertNull(lineFragments.get(0).getType());
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretColumnModeTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretColumnModeTest.java
index 9b94c44ab059..c4433cd15ca9 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretColumnModeTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretColumnModeTest.java
@@ -16,12 +16,12 @@
package com.intellij.openapi.editor;
import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.editor.impl.AbstractEditorTest;
import com.intellij.testFramework.EditorTestUtil;
-import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
import java.io.IOException;
-public class EditorMultiCaretColumnModeTest extends LightPlatformCodeInsightTestCase {
+public class EditorMultiCaretColumnModeTest extends AbstractEditorTest {
public void setUp() throws Exception {
super.setUp();
EditorTestUtil.enableMultipleCarets();
@@ -192,8 +192,99 @@ public class EditorMultiCaretColumnModeTest extends LightPlatformCodeInsightTest
"bbbb bb<selection>bb<caret></selection>");
}
+ public void testMoveToSelectionStart() throws Exception {
+ init("a");
+ mouse().clickAt(0, 2).dragTo(0, 4).release();
+ verifyCaretsAndSelections(0, 4, 0, 2, 0, 4);
+
+ executeAction("EditorLeft");
+ verifyCaretsAndSelections(0, 2, 0, 2, 0, 2);
+ }
+
+ public void testMoveToSelectionEnd() throws Exception {
+ init("a");
+ mouse().clickAt(0, 4).dragTo(0, 2).release();
+ verifyCaretsAndSelections(0, 2, 0, 2, 0, 4);
+
+ executeAction("EditorRight");
+ verifyCaretsAndSelections(0, 4, 0, 4, 0, 4);
+ }
+
+ public void testReverseBlockSelection() throws Exception {
+ init("a");
+ mouse().clickAt(0, 4).dragTo(0, 3).release();
+ verifyCaretsAndSelections(0, 3, 0, 3, 0, 4);
+
+ executeAction("EditorRightWithSelection");
+ verifyCaretsAndSelections(0, 4, 0, 4, 0, 4);
+ }
+
+ public void testSelectionWithKeyboardInEmptySpace() throws Exception {
+ init("\n\n");
+ mouse().clickAt(1, 1);
+ verifyCaretsAndSelections(1, 1, 1, 1, 1, 1);
+
+ executeAction("EditorRightWithSelection");
+ verifyCaretsAndSelections(1, 2, 1, 1, 1, 2);
+
+ executeAction("EditorDownWithSelection");
+ verifyCaretsAndSelections(1, 2, 1, 1, 1, 2,
+ 2, 2, 2, 1, 2, 2);
+
+ executeAction("EditorLeftWithSelection");
+ verifyCaretsAndSelections(1, 1, 1, 1, 1, 1,
+ 2, 1, 2, 1, 2, 1);
+
+ executeAction("EditorLeftWithSelection");
+ verifyCaretsAndSelections(1, 0, 1, 0, 1, 1,
+ 2, 0, 2, 0, 2, 1);
+
+ executeAction("EditorUpWithSelection");
+ verifyCaretsAndSelections(1, 0, 1, 0, 1, 1);
+
+ executeAction("EditorUpWithSelection");
+ verifyCaretsAndSelections(0, 0, 0, 0, 0, 1,
+ 1, 0, 1, 0, 1, 1);
+
+ executeAction("EditorRightWithSelection");
+ verifyCaretsAndSelections(0, 1, 0, 1, 0, 1,
+ 1, 1, 1, 1, 1, 1);
+
+ executeAction("EditorRightWithSelection");
+ verifyCaretsAndSelections(0, 2, 0, 1, 0, 2,
+ 1, 2, 1, 1, 1, 2);
+
+ executeAction("EditorDownWithSelection");
+ verifyCaretsAndSelections(1, 2, 1, 1, 1, 2);
+
+ executeAction("EditorLeftWithSelection");
+ verifyCaretsAndSelections(1, 1, 1, 1, 1, 1);
+ }
+
+ public void testBlockSelection() throws Exception {
+ init("a\n" +
+ "bbb\n" +
+ "ccccc");
+ mouse().clickAt(2, 4).dragTo(0, 1).release();
+ verifyCaretsAndSelections(0, 1, 0, 1, 0, 4,
+ 1, 1, 1, 1, 1, 4,
+ 2, 1, 2, 1, 2, 4);
+ }
+
+ public void testTyping() throws Exception {
+ init("a\n" +
+ "bbb\n" +
+ "ccccc");
+ mouse().clickAt(0, 2).dragTo(2, 3).release();
+ type('S');
+ checkResultByText("a S<caret>\n" +
+ "bbS<caret>\n" +
+ "ccS<caret>cc");
+ }
+
private void init(String text) throws IOException {
configureFromFileText(getTestName(false) + ".txt", text);
+ EditorTestUtil.setEditorVisibleSize(myEditor, 1000, 1000);
((EditorEx)myEditor).setColumnMode(true);
}
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretUndoRedoTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretUndoRedoTest.java
index 0b168c4cf813..6f13af47dee5 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretUndoRedoTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretUndoRedoTest.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.impl.CurrentEditorProvider;
import com.intellij.openapi.command.impl.UndoManagerImpl;
import com.intellij.openapi.command.undo.UndoManager;
+import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.impl.AbstractEditorTest;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.TextEditor;
@@ -29,6 +30,8 @@ import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.TestFileType;
import org.jetbrains.annotations.NotNull;
+import java.io.IOException;
+
public class EditorMultiCaretUndoRedoTest extends AbstractEditorTest {
private CurrentEditorProvider mySavedCurrentEditorProvider;
@@ -58,9 +61,7 @@ public class EditorMultiCaretUndoRedoTest extends AbstractEditorTest {
public void testUndoRedo() throws Exception {
init("some<caret> text<caret>\n" +
"some <selection><caret>other</selection> <selection>text<caret></selection>\n" +
- "<selection>ano<caret>ther</selection> line",
- TestFileType.TEXT);
- setupEditorProvider();
+ "<selection>ano<caret>ther</selection> line");
type('A');
executeAction("EditorDelete");
mouse().clickAt(0, 1);
@@ -80,6 +81,25 @@ public class EditorMultiCaretUndoRedoTest extends AbstractEditorTest {
"A<caret> line");
}
+ public void testBlockSelectionStateAfterUndo() throws Exception {
+ init("a");
+ ((EditorEx)myEditor).setColumnMode(true);
+ mouse().clickAt(0, 2);
+ type('b');
+ undo();
+ executeAction("EditorRightWithSelection");
+ verifyCaretsAndSelections(0, 3, 0, 2, 0, 3);
+ }
+
+ public void testBlockSelectionStateAfterUndo2() throws Exception {
+ init("a");
+ ((EditorEx)myEditor).setColumnMode(true);
+ mouse().clickAt(0, 0).dragTo(0, 2).release();
+ type('b');
+ undo();
+ verifyCaretsAndSelections(0, 2, 0, 0, 0, 2);
+ }
+
private void checkResult(final String text) {
CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
@Override
@@ -105,7 +125,9 @@ public class EditorMultiCaretUndoRedoTest extends AbstractEditorTest {
return TextEditorProvider.getInstance().getTextEditor(myEditor);
}
- private static void setupEditorProvider() {
+ private void init(String text) throws IOException {
+ init(text, TestFileType.TEXT);
+ EditorTestUtil.setEditorVisibleSize(myEditor, 1000, 1000);
getUndoManager().setEditorProvider(new CurrentEditorProvider() {
@Override
public FileEditor getCurrentEditor() {
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 90a82e972379..42faeaa86e85 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
@@ -49,6 +49,30 @@ public class SelectUnselectOccurrenceActionsTest extends LightPlatformCodeInsigh
super.tearDown();
}
+ public void testAllWithoutInitialSelection() throws Exception {
+ init("some t<caret>ext\n" +
+ "some texts\n" +
+ "another text here"
+ );
+ executeSelectAllAction();
+ checkResult("some <selection>t<caret>ext</selection>\n" +
+ "some texts\n" +
+ "another <selection>t<caret>ext</selection> here");
+ }
+
+ public void testAllWithInitialWholeWordSelection() throws Exception {
+ init("some <selection>t<caret>ext</selection>\n" +
+ "some texts\n" +
+ "some texts\n" +
+ "another text here");
+ executeSelectAllAction();
+ checkResult("some <selection>t<caret>ext</selection>\n" +
+ "some texts\n" +
+ "some texts\n" +
+ "another <selection>t<caret>ext</selection> here");
+ assertEquals(0, hintCount);
+ }
+
public void testNoInitialSelection() throws Exception {
init("some t<caret>ext\n" +
"some texts\n" +
@@ -182,6 +206,10 @@ public class SelectUnselectOccurrenceActionsTest extends LightPlatformCodeInsigh
}
private void executeReverseAction() {
- myFixture.performEditorAction(IdeActions.ACTION_UNSELECT_LAST_OCCURENCE);
+ myFixture.performEditorAction(IdeActions.ACTION_UNSELECT_PREVIOUS_OCCURENCE);
+ }
+
+ private void executeSelectAllAction() {
+ myFixture.performEditorAction(IdeActions.ACTION_SELECT_ALL_OCCURRENCES);
}
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/AbstractEditorTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/AbstractEditorTest.java
index bbb8de3200cc..2c460a5ad6b0 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/AbstractEditorTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/AbstractEditorTest.java
@@ -15,9 +15,7 @@
*/
package com.intellij.openapi.editor.impl;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.FoldRegion;
-import com.intellij.openapi.editor.FoldingModel;
+import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.ex.FoldingModelEx;
import com.intellij.openapi.editor.impl.softwrap.mapping.CachingSoftWrapDataMapper;
import com.intellij.openapi.util.Pair;
@@ -220,4 +218,18 @@ public abstract class AbstractEditorTest extends LightPlatformCodeInsightTestCas
public EditorMouseFixture mouse() {
return new EditorMouseFixture((EditorImpl)myEditor);
}
+
+ // for each caret its visual position and visual positions of selection start an and should be provided in the following order:
+ // caretLine, caretColumn, selectionStartLine, selectionStartColumn, selectionEndLine, selectionEndColumn
+ public static void verifyCaretsAndSelections(int... coordinates) {
+ int caretCount = coordinates.length / 6;
+ List<Caret> carets = myEditor.getCaretModel().getAllCarets();
+ assertEquals("Unexpected caret count", caretCount, carets.size());
+ for (int i = 0; i < caretCount; i++) {
+ Caret caret = carets.get(i);
+ assertEquals("Unexpected position for caret " + (i + 1), new VisualPosition(coordinates[i * 6], coordinates[i * 6 + 1]), caret.getVisualPosition());
+ assertEquals("Unexpected selection start for caret " + (i + 1), new VisualPosition(coordinates[i * 6 + 2], coordinates[i * 6 + 3]), caret.getSelectionStartPosition());
+ assertEquals("Unexpected selection end for caret " + (i + 1), new VisualPosition(coordinates[i * 6 + 4], coordinates[i * 6 + 5]), caret.getSelectionEndPosition());
+ }
+ }
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/IterationStateTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/IterationStateTest.java
index 2b8f99e2693a..2502e767b331 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/IterationStateTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/IterationStateTest.java
@@ -15,21 +15,42 @@
*/
package com.intellij.openapi.editor.impl;
+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.fileTypes.PlainTextFileType;
import com.intellij.testFramework.EditorTestUtil;
+import com.intellij.testFramework.fixtures.EditorMouseFixture;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
-import org.jetbrains.annotations.NotNull;
import org.junit.Assert;
import java.awt.*;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
public class IterationStateTest extends LightPlatformCodeInsightFixtureTestCase {
+ private Color DEFAULT_BACKGROUND;
+ private Color CARET_ROW_BACKGROUND;
+ private Color SELECTION_BACKGROUND;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ EditorColorsScheme colorsScheme = EditorColorsManager.getInstance().getGlobalScheme();
+ DEFAULT_BACKGROUND = colorsScheme.getDefaultBackground();
+ CARET_ROW_BACKGROUND = colorsScheme.getColor(EditorColors.CARET_ROW_COLOR);
+ SELECTION_BACKGROUND = colorsScheme.getColor(EditorColors.SELECTION_BACKGROUND_COLOR);
+ assertEquals(3, new HashSet<Color>(Arrays.asList(DEFAULT_BACKGROUND, CARET_ROW_BACKGROUND, SELECTION_BACKGROUND)).size());
+ }
+
public void testBlockSelection() {
- verifySplitting("aa,<block>bb\ncc,d</block>d",
+ init("aa,<block>bb\n" +
+ "cc,d</block>d");
+ verifySplitting(true,
new Segment(0, 3, Color.BLACK),
new Segment(3, 4, Color.WHITE),
new Segment(4, 5, Color.BLACK),
@@ -49,20 +70,106 @@ public class IterationStateTest extends LightPlatformCodeInsightFixtureTestCase
}
}
- private void verifySplitting(String text, Segment... expectedSegments) {
- myFixture.configureByText(PlainTextFileType.INSTANCE, text);
+ public void testColumnModeBlockSelection() {
+ EditorTestUtil.enableMultipleCarets();
+ try {
+ init("a\n" +
+ "bbb\n" +
+ "ccccc");
+ setColumnModeOn();
+ mouse().clickAt(0, 2).dragTo(2, 4).release();
+ verifySplitting(false,
+ new Segment(0, 1, DEFAULT_BACKGROUND),
+ new Segment(1, 2, DEFAULT_BACKGROUND).plus(1, DEFAULT_BACKGROUND).plus(2, SELECTION_BACKGROUND),
+ new Segment(2, 4, DEFAULT_BACKGROUND),
+ new Segment(4, 5, SELECTION_BACKGROUND),
+ new Segment(5, 6, DEFAULT_BACKGROUND).plus(1, SELECTION_BACKGROUND),
+ new Segment(6, 8, CARET_ROW_BACKGROUND),
+ new Segment(8, 10, SELECTION_BACKGROUND),
+ new Segment(10, 11, CARET_ROW_BACKGROUND));
+ }
+ finally {
+ EditorTestUtil.disableMultipleCarets();
+ }
+ }
+
+ public void testColumnModeBlockSelectionAtLastNonEmptyLine() {
+ EditorTestUtil.enableMultipleCarets();
+ try {
+ init("a\n" +
+ "bbb\n" +
+ "ccccc");
+ setColumnModeOn();
+ mouse().clickAt(0, 2).dragTo(2, 6).release();
+ verifySplitting(false,
+ new Segment(0, 1, DEFAULT_BACKGROUND),
+ new Segment(1, 2, DEFAULT_BACKGROUND).plus(1, DEFAULT_BACKGROUND).plus(4, SELECTION_BACKGROUND),
+ new Segment(2, 4, DEFAULT_BACKGROUND),
+ new Segment(4, 5, SELECTION_BACKGROUND),
+ new Segment(5, 6, DEFAULT_BACKGROUND).plus(3, SELECTION_BACKGROUND),
+ new Segment(6, 8, CARET_ROW_BACKGROUND),
+ new Segment(8, 11, SELECTION_BACKGROUND),
+ new Segment(11, 11, null).plus(1, SELECTION_BACKGROUND));
+ }
+ finally {
+ EditorTestUtil.disableMultipleCarets();
+ }
+ }
+
+ public void testColumnModeBlockSelectionAtLastEmptyLine() {
+ EditorTestUtil.enableMultipleCarets();
+ try {
+ init("a\n" +
+ "");
+ setColumnModeOn();
+ mouse().clickAt(1, 1).dragTo(1, 2).release();
+ verifySplitting(false,
+ new Segment(0, 1, DEFAULT_BACKGROUND),
+ new Segment(1, 2, DEFAULT_BACKGROUND),
+ new Segment(2, 2, null).plus(1, CARET_ROW_BACKGROUND).plus(1, SELECTION_BACKGROUND));
+ }
+ finally {
+ EditorTestUtil.disableMultipleCarets();
+ }
+ }
+
+ public void testColumnModeBlockSelectionAtEmptyLines() {
+ EditorTestUtil.enableMultipleCarets();
+ try {
+ init("\n");
+ setColumnModeOn();
+ mouse().clickAt(0, 1).dragTo(1, 2).release();
+ verifySplitting(false,
+ new Segment(0, 1, DEFAULT_BACKGROUND).plus(1, DEFAULT_BACKGROUND).plus(1, SELECTION_BACKGROUND),
+ new Segment(1, 1, null).plus(1, CARET_ROW_BACKGROUND).plus(1, SELECTION_BACKGROUND));
+ }
+ finally {
+ EditorTestUtil.disableMultipleCarets();
+ }
+ }
+
+ private void verifySplitting(boolean checkForegroundColor, Segment... expectedSegments) {
EditorEx editor = (EditorEx)myFixture.getEditor();
IterationState iterationState = new IterationState(editor, 0, editor.getDocument().getTextLength(), true);
try {
List<Segment> actualSegments = new ArrayList<Segment>();
do {
- actualSegments.add(new Segment(iterationState.getStartOffset(),
- iterationState.getEndOffset(),
- iterationState.getMergedAttributes().getForegroundColor()));
+ Segment segment = new Segment(iterationState.getStartOffset(),
+ iterationState.getEndOffset(),
+ checkForegroundColor ? iterationState.getMergedAttributes().getForegroundColor()
+ : iterationState.getMergedAttributes().getBackgroundColor());
+ readPastLineState(iterationState, segment);
+ actualSegments.add(segment);
iterationState.advance();
}
while (!iterationState.atEnd());
+ if (iterationState.hasPastFileEndBackgroundSegments()) {
+ Segment segment = new Segment(iterationState.getEndOffset(), iterationState.getEndOffset(), null);
+ readPastLineState(iterationState, segment);
+ actualSegments.add(segment);
+ }
+
Assert.assertArrayEquals(expectedSegments, actualSegments.toArray());
}
finally {
@@ -70,15 +177,46 @@ public class IterationStateTest extends LightPlatformCodeInsightFixtureTestCase
}
}
+ private static void readPastLineState(IterationState iterationState, Segment segment) {
+ while(iterationState.hasPastLineEndBackgroundSegment()) {
+ segment.plus(iterationState.getPastLineEndBackgroundSegmentWidth(), iterationState.getPastLineEndBackgroundAttributes().getBackgroundColor());
+ iterationState.advanceToNextPastLineEndBackgroundSegment();
+ }
+ }
+
+ private void init(String text) {
+ myFixture.configureByText(PlainTextFileType.INSTANCE, text);
+ EditorTestUtil.setEditorVisibleSize(myFixture.getEditor(), 1000, 1000);
+ }
+
+ private void setColumnModeOn() {
+ ((EditorEx)myFixture.getEditor()).setColumnMode(true);
+ }
+
+ private EditorMouseFixture mouse() {
+ return new EditorMouseFixture((EditorImpl)myFixture.getEditor());
+ }
+
private static class Segment {
private final int start;
private final int end;
- private final Color fgColor;
+ private final Color color;
+ private final List<Integer> pastLineEndSegmentWidths = new ArrayList<Integer>();
+ private final List<Color> pastLineEndSegmentColors = new ArrayList<Color>();
- private Segment(int start, int end, @NotNull Color fgColor) {
+ private Segment(int start, int end, Color color) {
this.start = start;
this.end = end;
- this.fgColor = fgColor;
+ this.color = color;
+ }
+
+ /**
+ * Adds a past-line-end background segment
+ */
+ private Segment plus(int width, Color color) {
+ pastLineEndSegmentWidths.add(width);
+ pastLineEndSegmentColors.add(color);
+ return this;
}
@Override
@@ -90,7 +228,9 @@ public class IterationStateTest extends LightPlatformCodeInsightFixtureTestCase
if (end != segment.end) return false;
if (start != segment.start) return false;
- if (!fgColor.equals(segment.fgColor)) return false;
+ if (color != null ? !color.equals(segment.color) : segment.color != null) return false;
+ if (!pastLineEndSegmentColors.equals(segment.pastLineEndSegmentColors)) return false;
+ if (!pastLineEndSegmentWidths.equals(segment.pastLineEndSegmentWidths)) return false;
return true;
}
@@ -99,7 +239,9 @@ public class IterationStateTest extends LightPlatformCodeInsightFixtureTestCase
public int hashCode() {
int result = start;
result = 31 * result + end;
- result = 31 * result + fgColor.hashCode();
+ result = 31 * result + (color != null ? color.hashCode() : 0);
+ result = 31 * result + pastLineEndSegmentWidths.hashCode();
+ result = 31 * result + pastLineEndSegmentColors.hashCode();
return result;
}
@@ -108,7 +250,9 @@ public class IterationStateTest extends LightPlatformCodeInsightFixtureTestCase
return "Segment{" +
"start=" + start +
", end=" + end +
- ", color=" + fgColor +
+ ", color=" + color +
+ (pastLineEndSegmentWidths.isEmpty() ? "" : ", pastLineEndSegmentWidths=" + pastLineEndSegmentWidths) +
+ (pastLineEndSegmentColors.isEmpty() ? "" : ", pastLineEndSegmentColors=" + pastLineEndSegmentColors) +
'}';
}
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTest.java
index cf53f977c813..09debec55b6b 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTest.java
@@ -17,29 +17,20 @@ package com.intellij.openapi.fileEditor;
import com.intellij.ide.ui.UISettings;
import com.intellij.mock.Mock;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.components.ExpandMacroToPathMap;
import com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
-import org.jdom.Document;
import org.jdom.Element;
-import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jps.model.serialization.PathMacroUtil;
import javax.swing.*;
import java.io.File;
-import java.io.IOException;
import java.util.Arrays;
import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
/**
* @author Dmitry Avdeev
@@ -77,17 +68,18 @@ public class FileEditorManagerTest extends FileEditorManagerTestCase {
openFiles(" <component name=\"FileEditorManager\">\n" +
" <leaf>\n" +
- " <file leaf-file-name=\"foo.xsd\" pinned=\"false\" current=\"true\" current-in-tab=\"true\">\n" +
- " <entry selected=\"true\" file=\"file://$PROJECT_DIR$/src/1.txt\">\n" +
- " <provider editor-type-id=\"mock\" selected=\"true\">\n" +
- " <state />\n" +
- " </provider>\n" +
- " <provider editor-type-id=\"text-editor\">\n" +
- " <state/>\n" +
+ " <file leaf-file-name=\"Bar.java\" pinned=\"false\" current=\"false\" current-in-tab=\"false\">\n" +
+ " <entry file=\"file://$PROJECT_DIR$/src/Bar.java\">\n" +
+ " <provider selected=\"true\" editor-type-id=\"text-editor\">\n" +
+ " <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"187\">\n" +
+ " <caret line=\"1\" column=\"26\" selection-start=\"45\" selection-end=\"45\" />\n" +
+ " <folding>\n" +
+ " <element signature=\"e#69#70#0\" expanded=\"true\" />\n" +
+ " </folding>\n" +
+ " </state>\n" +
" </provider>\n" +
" </entry>\n" +
" </file>\n" +
- " </leaf>\n" +
" </component>\n");
FileEditor[] selectedEditors = myManager.getSelectedEditors();
assertEquals(1, selectedEditors.length);
@@ -157,24 +149,6 @@ public class FileEditorManagerTest extends FileEditorManagerTestCase {
assertEquals(Arrays.asList(fileNames), names);
}
- private void openFiles(String s) throws IOException, JDOMException, InterruptedException, ExecutionException {
- Document document = JDOMUtil.loadDocument(s);
- Element rootElement = document.getRootElement();
- ExpandMacroToPathMap map = new ExpandMacroToPathMap();
- map.addMacroExpand(PathMacroUtil.PROJECT_DIR_MACRO_NAME, getTestDataPath());
- map.substitute(rootElement, true, true);
-
- myManager.readExternal(rootElement);
-
- Future<?> future = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
- @Override
- public void run() {
- myManager.getMainSplitters().openFiles();
- }
- });
- future.get();
- }
-
@Override
protected String getTestDataPath() {
return PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/platform/platform-tests/testData/fileEditorManager";
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTestCase.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTestCase.java
index aa528681114b..28d5def0a218 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTestCase.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileEditorManagerTestCase.java
@@ -1,13 +1,27 @@
package com.intellij.openapi.fileEditor;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.ExpandMacroToPathMap;
import com.intellij.openapi.components.impl.ComponentManagerImpl;
import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager;
import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
import com.intellij.openapi.fileEditor.impl.FileEditorProviderManagerImpl;
+import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import com.intellij.ui.docking.DockManager;
+import com.intellij.util.ui.UIUtil;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jetbrains.jps.model.serialization.PathMacroUtil;
+
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
/**
* @author Dmitry Avdeev
@@ -40,4 +54,30 @@ public abstract class FileEditorManagerTestCase extends LightPlatformCodeInsight
protected VirtualFile getFile(String path) {
return LocalFileSystem.getInstance().refreshAndFindFileByPath(getTestDataPath() + path);
}
+
+ protected void openFiles(String s) throws IOException, JDOMException, InterruptedException, ExecutionException {
+ Document document = JDOMUtil.loadDocument(s);
+ Element rootElement = document.getRootElement();
+ ExpandMacroToPathMap map = new ExpandMacroToPathMap();
+ map.addMacroExpand(PathMacroUtil.PROJECT_DIR_MACRO_NAME, getTestDataPath());
+ map.substitute(rootElement, true, true);
+
+ myManager.readExternal(rootElement);
+
+ Future<?> future = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ @Override
+ public void run() {
+ myManager.getMainSplitters().openFiles();
+ }
+ });
+ while (true) {
+ try {
+ future.get(100, TimeUnit.MILLISECONDS);
+ return;
+ }
+ catch (TimeoutException e) {
+ UIUtil.dispatchAllInvocationEvents();
+ }
+ }
+ }
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/EnforcedPlaintTextFileTypeManagerTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/EnforcedPlaintTextFileTypeManagerTest.java
new file mode 100644
index 000000000000..2fe27875e2e9
--- /dev/null
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/EnforcedPlaintTextFileTypeManagerTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.fileTypes;
+
+import com.intellij.openapi.file.exclude.EnforcedPlainTextFileTypeFactory;
+import com.intellij.openapi.file.exclude.EnforcedPlainTextFileTypeManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+public class EnforcedPlaintTextFileTypeManagerTest extends LightPlatformCodeInsightFixtureTestCase {
+ public void testMarkAsPlainText() {
+ EnforcedPlainTextFileTypeManager manager = EnforcedPlainTextFileTypeManager.getInstance();
+ VirtualFile file = myFixture.getTempDirFixture().createFile("test.java");
+ FileType originalType = file.getFileType();
+ assertEquals("JAVA", originalType.getName());
+ manager.markAsPlainText(file);
+ FileType changedType = file.getFileType();
+ assertEquals(EnforcedPlainTextFileTypeFactory.ENFORCED_PLAIN_TEXT, changedType.getName());
+ manager.resetOriginalFileType(file);
+ FileType revertedType = file.getFileType();
+ assertEquals(originalType, revertedType);
+ }
+}
diff --git a/platform/platform-tests/testSrc/com/intellij/remotesdk/RemoteFileTest.java b/platform/platform-tests/testSrc/com/intellij/remotesdk/RemoteFileTest.java
index d53ae4af054a..7133c987f4b0 100644
--- a/platform/platform-tests/testSrc/com/intellij/remotesdk/RemoteFileTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/remotesdk/RemoteFileTest.java
@@ -15,6 +15,8 @@
*/
package com.intellij.remotesdk;
+import com.intellij.remote.RemoteFile;
+import com.intellij.remote.RemoteSdkCredentialsHolder;
import junit.framework.TestCase;
/**
diff --git a/platform/platform-tests/testSrc/com/intellij/util/io/PersistentMapTest.java b/platform/platform-tests/testSrc/com/intellij/util/io/PersistentMapTest.java
index f40716bbecc8..7a4173039a8c 100644
--- a/platform/platform-tests/testSrc/com/intellij/util/io/PersistentMapTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/util/io/PersistentMapTest.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.util.io;
import com.intellij.openapi.util.io.FileUtil;
@@ -8,6 +23,7 @@ import com.intellij.util.containers.IntObjectCache;
import com.intellij.util.io.storage.AbstractStorage;
import gnu.trove.THashSet;
import junit.framework.TestCase;
+import org.jetbrains.annotations.NotNull;
import java.io.*;
import java.util.*;
@@ -424,13 +440,13 @@ public class PersistentMapTest extends TestCase {
FileUtil.createParentDirs(file);
EnumeratorStringDescriptor stringDescriptor = new EnumeratorStringDescriptor();
class PathCollectionExternalizer implements DataExternalizer<Collection<String>> {
- public void save(DataOutput out, Collection<String> value) throws IOException {
+ public void save(@NotNull DataOutput out, Collection<String> value) throws IOException {
for (String str : value) {
IOUtil.writeString(str, out);
}
}
- public Collection<String> read(DataInput in) throws IOException {
+ public Collection<String> read(@NotNull DataInput in) throws IOException {
final Set<String> result = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
final DataInputStream stream = (DataInputStream)in;
while (stream.available() > 0) {
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 8d1ef81ba057..c0ed5c0ba3e1 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.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.
@@ -39,7 +39,7 @@ public abstract class ProjectRootManager implements ModificationTracker {
* @param project the project for which the instance is requested.
* @return the instance.
*/
- public static ProjectRootManager getInstance(Project project) {
+ public static ProjectRootManager getInstance(@NotNull Project project) {
final ProjectRootManager service = ServiceManager.getService(project, ProjectRootManager.class);
if (service != null) return service;
return project.getComponent(ProjectRootManager.class);
diff --git a/platform/projectModel-impl/src/com/intellij/core/CoreModule.java b/platform/projectModel-impl/src/com/intellij/core/CoreModule.java
index 86fbdf7275d7..fc4f2de73b36 100644
--- a/platform/projectModel-impl/src/com/intellij/core/CoreModule.java
+++ b/platform/projectModel-impl/src/com/intellij/core/CoreModule.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.
@@ -177,51 +177,61 @@ public class CoreModule extends MockComponentManager implements ModuleEx {
throw new UnsupportedOperationException();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleScope() {
return myModuleScopeProvider.getModuleScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleScope(boolean includeTests) {
return myModuleScopeProvider.getModuleScope(includeTests);
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithLibrariesScope() {
return myModuleScopeProvider.getModuleWithLibrariesScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithDependenciesScope() {
return myModuleScopeProvider.getModuleWithDependenciesScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleContentScope() {
return myModuleScopeProvider.getModuleContentScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleContentWithDependenciesScope() {
return myModuleScopeProvider.getModuleContentWithDependenciesScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithDependenciesAndLibrariesScope(boolean includeTests) {
return myModuleScopeProvider.getModuleWithDependenciesAndLibrariesScope(includeTests);
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithDependentsScope() {
return myModuleScopeProvider.getModuleWithDependentsScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleTestsWithDependentsScope() {
return myModuleScopeProvider.getModuleTestsWithDependentsScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleRuntimeScope(boolean includeTests) {
return myModuleScopeProvider.getModuleRuntimeScope(includeTests);
diff --git a/platform/projectModel-impl/src/com/intellij/core/CoreModuleScopeProvider.java b/platform/projectModel-impl/src/com/intellij/core/CoreModuleScopeProvider.java
index aeafc197aed5..1473232df5db 100644
--- a/platform/projectModel-impl/src/com/intellij/core/CoreModuleScopeProvider.java
+++ b/platform/projectModel-impl/src/com/intellij/core/CoreModuleScopeProvider.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.core;
import com.intellij.openapi.module.impl.ModuleScopeProvider;
import com.intellij.psi.search.GlobalSearchScope;
+import org.jetbrains.annotations.NotNull;
/**
* Author: dmitrylomov
@@ -25,51 +26,61 @@ public class CoreModuleScopeProvider implements ModuleScopeProvider {
public CoreModuleScopeProvider() {
}
+ @NotNull
@Override
public GlobalSearchScope getModuleScope() {
throw new UnsupportedOperationException();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleScope(boolean includeTests) {
throw new UnsupportedOperationException();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithLibrariesScope() {
throw new UnsupportedOperationException();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithDependenciesScope() {
throw new UnsupportedOperationException();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleContentScope() {
throw new UnsupportedOperationException();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleContentWithDependenciesScope() {
throw new UnsupportedOperationException();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithDependenciesAndLibrariesScope(boolean includeTests) {
throw new UnsupportedOperationException();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithDependentsScope() {
throw new UnsupportedOperationException();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleTestsWithDependentsScope() {
throw new UnsupportedOperationException();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleRuntimeScope(boolean includeTests) {
throw new UnsupportedOperationException();
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 6041f613f1a0..9cabfb68416b 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
@@ -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.
@@ -477,10 +477,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
@Override
@NotNull
- public Module loadModule(@NotNull String filePath) throws InvalidDataException,
- IOException,
- JDOMException,
- ModuleWithNameAlreadyExists {
+ public Module loadModule(@NotNull String filePath) throws InvalidDataException, IOException, JDOMException, ModuleWithNameAlreadyExists {
myModificationCount++;
final ModifiableModuleModel modifiableModel = getModifiableModel();
final Module module = modifiableModel.loadModule(filePath);
@@ -745,10 +742,9 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
}
}
- private Module loadModuleInternal(String filePath)
- throws ModuleWithNameAlreadyExists, IOException, StateStorageException {
-
- final VirtualFile moduleFile = StandardFileSystems.local().findFileByPath(resolveShortWindowsName(filePath));
+ private Module loadModuleInternal(String filePath) throws ModuleWithNameAlreadyExists, IOException, StateStorageException {
+ filePath = resolveShortWindowsName(filePath);
+ final VirtualFile moduleFile = StandardFileSystems.local().findFileByPath(filePath);
if (moduleFile == null || !moduleFile.exists()) {
throw new IOException(ProjectBundle.message("module.file.does.not.exist.error", filePath));
}
diff --git a/platform/remote-servers/impl/resources/resources/cloud.properties b/platform/remote-servers/impl/resources/resources/cloud.properties
index f7637990f0d8..24aae89b33a7 100644
--- a/platform/remote-servers/impl/resources/resources/cloud.properties
+++ b/platform/remote-servers/impl/resources/resources/cloud.properties
@@ -5,4 +5,4 @@ failed.add.remote=Failed to add {0} repository as remote
failed.reset.remote=Failed to set {0} repository as remote
cloning.existing.application=Cloning existing {0} application
fetching.application=Fetching {0} application
-
+run.configuration.name={0} - {1}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.form b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.form
new file mode 100644
index 000000000000..bbfd6da1afcc
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.form
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.remoteServer.util.CloudAccountSelectionEditor">
+ <grid id="27dc6" binding="myMainPanel" 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>
+ <xy x="20" y="20" width="500" height="400"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="82588" class="javax.swing.JComboBox" binding="myServerComboBox">
+ <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>
+ <grid id="27f9c" binding="myServerConfigurablePanel" custom-create="true" 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="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"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children/>
+ </grid>
+ <vspacer id="dcc88">
+ <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>
+ </children>
+ </grid>
+</form>
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java
new file mode 100644
index 000000000000..aab46e76a3c7
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.execution.RunManagerEx;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.configurations.ConfigurationType;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModulePointer;
+import com.intellij.openapi.module.ModulePointerManager;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import com.intellij.remoteServer.ServerType;
+import com.intellij.remoteServer.configuration.RemoteServer;
+import com.intellij.remoteServer.configuration.RemoteServersManager;
+import com.intellij.remoteServer.impl.configuration.RemoteServerConfigurable;
+import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerConfigurationType;
+import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
+import com.intellij.remoteServer.impl.configuration.deployment.ModuleDeploymentSourceImpl;
+import com.intellij.util.text.UniqueNameGenerator;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * @author michael.golubev
+ */
+public class CloudAccountSelectionEditor<SC extends CloudConfigurationBase,
+ DC extends CloudDeploymentNameConfiguration,
+ ST extends ServerType<SC>> implements Disposable {
+
+ private static final Logger LOG = Logger.getInstance("#" + CloudAccountSelectionEditor.class.getName());
+
+ private JComboBox myServerComboBox;
+ private JPanel myServerConfigurablePanel;
+ private JPanel myMainPanel;
+
+ private final ST myCloudType;
+
+ private RemoteServer<SC> myNewServer;
+ private RemoteServerConfigurable myServerConfigurable;
+
+ protected CloudAccountSelectionEditor(ST cloudType) {
+ myCloudType = cloudType;
+ }
+
+ private void createUIComponents() {
+ myServerConfigurablePanel = createServerConfigurablePanel();
+ }
+
+ public void initUI() {
+ myServerComboBox.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ onAccountSelectionChanged();
+ }
+ });
+
+ for (RemoteServer<SC> server : RemoteServersManager.getInstance().getServers(myCloudType)) {
+ myServerComboBox.addItem(new ServerItem(server));
+ }
+ myServerComboBox.addItem(new ServerItem(myNewServer));
+ }
+
+ private void onAccountSelectionChanged() {
+ myServerConfigurablePanel.setVisible(getSelectedServerItem().isNew());
+ }
+
+ protected JPanel createServerConfigurablePanel() {
+ myNewServer = RemoteServersManager.getInstance().createServer(myCloudType, generateServerName());
+ myServerConfigurable = new RemoteServerConfigurable(myNewServer, null, true);
+ myServerConfigurablePanel = (JPanel)myServerConfigurable.createComponent();
+ return myServerConfigurablePanel;
+ }
+
+ private String generateServerName() {
+ return UniqueNameGenerator.generateUniqueName(myCloudType.getPresentableName(), new Condition<String>() {
+
+ @Override
+ public boolean value(String s) {
+ for (RemoteServer<?> server : RemoteServersManager.getInstance().getServers()) {
+ if (server.getName().equals(s)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ });
+ }
+
+ public DeployToServerRunConfiguration<SC, DC> createRunConfiguration(Module module, DC deploymentConfiguration) {
+ Project project = module.getProject();
+
+ RemoteServer<SC> server = getServer();
+ if (server == null) {
+ return null;
+ }
+
+ if (getSelectedServerItem().isNew()) {
+ RemoteServersManager.getInstance().addServer(server);
+ }
+
+ String serverName = server.getName();
+
+ String name = generateRunConfigurationName(serverName, module.getName());
+
+ final RunManagerEx runManager = RunManagerEx.getInstanceEx(project);
+ final RunnerAndConfigurationSettings runSettings
+ = runManager.createRunConfiguration(name, getRunConfigurationType().getConfigurationFactories()[0]);
+
+ final DeployToServerRunConfiguration<SC, DC> result = (DeployToServerRunConfiguration<SC, DC>)runSettings.getConfiguration();
+
+ runManager.addConfiguration(runSettings, false);
+ runManager.setSelectedConfiguration(runSettings);
+
+ result.setServerName(serverName);
+
+ final ModulePointer modulePointer = ModulePointerManager.getInstance(project).create(module);
+ result.setDeploymentSource(new ModuleDeploymentSourceImpl(modulePointer));
+
+ result.setDeploymentConfiguration(deploymentConfiguration);
+
+ return result;
+ }
+
+ protected String generateRunConfigurationName(String serverName, String moduleName) {
+ return CloudBundle.getText("run.configuration.name", serverName, moduleName);
+ }
+
+ protected void handleError(ConfigurationException e) {
+ LOG.info(e);
+ }
+
+ public RemoteServer<SC> getServer() {
+ try {
+ return doGetServer();
+ }
+ catch (ConfigurationException e) {
+ handleError(e);
+ return null;
+ }
+ }
+
+ private RemoteServer<SC> doGetServer() throws ConfigurationException {
+ ServerItem serverItem = getSelectedServerItem();
+ if (serverItem.isNew()) {
+ myServerConfigurable.apply();
+ myNewServer.setName(myServerConfigurable.getDisplayName());
+ }
+ return serverItem.getServer();
+ }
+
+ public void validate() throws ConfigurationException {
+ doGetServer();
+ }
+
+ private ServerItem getSelectedServerItem() {
+ return (ServerItem)myServerComboBox.getSelectedItem();
+ }
+
+ private DeployToServerConfigurationType getRunConfigurationType() {
+ String id = DeployToServerConfigurationType.getId(myCloudType);
+ for (ConfigurationType configurationType : ConfigurationType.CONFIGURATION_TYPE_EP.getExtensions()) {
+ if (configurationType instanceof DeployToServerConfigurationType) {
+ DeployToServerConfigurationType deployConfigurationType = (DeployToServerConfigurationType)configurationType;
+ if (deployConfigurationType.getId().equals(id)) {
+ return deployConfigurationType;
+ }
+ }
+ }
+ return null;
+ }
+
+ public JPanel getMainPanel() {
+ return myMainPanel;
+ }
+
+ @Override
+ public void dispose() {
+ myServerConfigurable.disposeUIResources();
+ }
+
+ private class ServerItem {
+
+ private final RemoteServer<SC> myServer;
+
+ public ServerItem(RemoteServer<SC> server) {
+ myServer = server;
+ }
+
+ public boolean isNew() {
+ return myServer == myNewServer;
+ }
+
+ public RemoteServer<SC> getServer() {
+ return myServer;
+ }
+
+ @Override
+ public String toString() {
+ return isNew() ? "New account..." : myServer.getName();
+ }
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudSupportConfigurableBase.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudSupportConfigurableBase.java
index e27a892594f3..4aecb257f7b4 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudSupportConfigurableBase.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudSupportConfigurableBase.java
@@ -1,39 +1,24 @@
package com.intellij.remoteServer.util;
import com.intellij.ProjectTopics;
-import com.intellij.execution.RunManagerEx;
-import com.intellij.execution.RunnerAndConfigurationSettings;
-import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportConfigurable;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModulePointer;
-import com.intellij.openapi.module.ModulePointerManager;
-import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.ModuleAdapter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.MessageType;
-import com.intellij.openapi.util.Condition;
-import com.intellij.remoteServer.ServerType;
+import com.intellij.openapi.util.Disposer;
import com.intellij.remoteServer.configuration.RemoteServer;
-import com.intellij.remoteServer.configuration.RemoteServersManager;
-import com.intellij.remoteServer.impl.configuration.RemoteServerConfigurable;
-import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerConfigurationType;
-import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
-import com.intellij.remoteServer.impl.configuration.deployment.ModuleDeploymentSourceImpl;
import com.intellij.remoteServer.runtime.Deployment;
import com.intellij.remoteServer.runtime.ServerConnection;
import com.intellij.remoteServer.runtime.ServerConnector;
import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.messages.MessageBusConnection;
-import com.intellij.util.text.UniqueNameGenerator;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicReference;
@@ -43,43 +28,24 @@ import java.util.concurrent.atomic.AtomicReference;
public abstract class CloudSupportConfigurableBase<
SC extends CloudConfigurationBase,
DC extends CloudDeploymentNameConfiguration,
- ST extends ServerType<SC>,
SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>>
extends FrameworkSupportConfigurable {
private final Project myModelProject;
- private RemoteServer<SC> myNewServer;
- private ST myCloudType;
- private RemoteServerConfigurable myServerConfigurable;
- private JPanel myServerConfigurablePanel;
private boolean myInitialized = false;
- public CloudSupportConfigurableBase(FrameworkSupportModel frameworkSupportModel, ST cloudType) {
+ public CloudSupportConfigurableBase(FrameworkSupportModel frameworkSupportModel) {
myModelProject = frameworkSupportModel.getProject();
- myCloudType = cloudType;
}
@Override
public void dispose() {
- myServerConfigurable.disposeUIResources();
+ Disposer.dispose(getAccountSelectionEditor());
}
protected void initUI() {
- JComboBox serverComboBox = getServerComboBox();
-
- serverComboBox.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- onAccountSelectionChanged();
- }
- });
-
- for (RemoteServer<SC> server : RemoteServersManager.getInstance().getServers(myCloudType)) {
- serverComboBox.addItem(new ServerItem(server));
- }
- serverComboBox.addItem(new ServerItem(myNewServer));
+ getAccountSelectionEditor().initUI();
}
protected void reloadExistingApplications() {
@@ -137,21 +103,6 @@ public abstract class CloudSupportConfigurableBase<
}
}
- private ServerItem getSelectedServerItem() {
- return (ServerItem)getServerComboBox().getSelectedItem();
- }
-
- private void onAccountSelectionChanged() {
- myServerConfigurablePanel.setVisible(getSelectedServerItem().isNew());
- }
-
- protected JPanel createServerConfigurablePanel() {
- myNewServer = RemoteServersManager.getInstance().createServer(myCloudType, generateServerName());
- myServerConfigurable = new RemoteServerConfigurable(myNewServer, null, true);
- myServerConfigurablePanel = (JPanel)myServerConfigurable.createComponent();
- return myServerConfigurablePanel;
- }
-
protected void showMessage(String message, MessageType messageType) {
getNotifier().showMessage(message, messageType);
}
@@ -160,77 +111,8 @@ public abstract class CloudSupportConfigurableBase<
return myModelProject;
}
- private String generateServerName() {
- return UniqueNameGenerator.generateUniqueName(myCloudType.getPresentableName(), new Condition<String>() {
-
- @Override
- public boolean value(String s) {
- for (RemoteServer<?> server : RemoteServersManager.getInstance().getServers()) {
- if (server.getName().equals(s)) {
- return false;
- }
- }
- return true;
- }
- });
- }
-
- private DeployToServerConfigurationType getRunConfigurationType() {
- String id = DeployToServerConfigurationType.getId(myCloudType);
- for (ConfigurationType configurationType : ConfigurationType.CONFIGURATION_TYPE_EP.getExtensions()) {
- if (configurationType instanceof DeployToServerConfigurationType) {
- DeployToServerConfigurationType deployConfigurationType = (DeployToServerConfigurationType)configurationType;
- if (deployConfigurationType.getId().equals(id)) {
- return deployConfigurationType;
- }
- }
- }
- return null;
- }
-
protected RemoteServer<SC> getServer() {
- ServerItem serverItem = getSelectedServerItem();
- if (serverItem.isNew()) {
- try {
- myServerConfigurable.apply();
- myNewServer.setName(myServerConfigurable.getDisplayName());
- }
- catch (ConfigurationException e) {
- showMessage(e.getMessage(), MessageType.ERROR);
- return null;
- }
- }
- return serverItem.getServer();
- }
-
- protected DeployToServerRunConfiguration<SC, DC> createRunConfiguration(String name, Module module, DC deploymentConfiguration) {
- Project project = module.getProject();
-
- RemoteServer<SC> server = getServer();
-
- if (getSelectedServerItem().isNew()) {
- RemoteServersManager.getInstance().addServer(server);
- }
-
- String serverName = server.getName();
-
- final RunManagerEx runManager = RunManagerEx.getInstanceEx(project);
- final RunnerAndConfigurationSettings runSettings
- = runManager.createRunConfiguration(name, getRunConfigurationType().getConfigurationFactories()[0]);
-
- final DeployToServerRunConfiguration<SC, DC> result = (DeployToServerRunConfiguration<SC, DC>)runSettings.getConfiguration();
-
- runManager.addConfiguration(runSettings, false);
- runManager.setSelectedConfiguration(runSettings);
-
- result.setServerName(serverName);
-
- final ModulePointer modulePointer = ModulePointerManager.getInstance(project).create(module);
- result.setDeploymentSource(new ModuleDeploymentSourceImpl(modulePointer));
-
- result.setDeploymentConfiguration(deploymentConfiguration);
-
- return result;
+ return getAccountSelectionEditor().getServer();
}
protected void runOnModuleAdded(final Module module, final Runnable runnable) {
@@ -250,36 +132,14 @@ public abstract class CloudSupportConfigurableBase<
}
}
- protected abstract JComboBox getExistingComboBox();
+ protected abstract CloudAccountSelectionEditor<SC, DC, ?> getAccountSelectionEditor();
- protected abstract JComboBox getServerComboBox();
+ protected abstract JComboBox getExistingComboBox();
protected abstract void updateApplicationUI();
protected abstract CloudNotifier getNotifier();
- protected class ServerItem {
-
- private final RemoteServer<SC> myServer;
-
- public ServerItem(RemoteServer<SC> server) {
- myServer = server;
- }
-
- public boolean isNew() {
- return myServer == myNewServer;
- }
-
- public RemoteServer<SC> getServer() {
- return myServer;
- }
-
- @Override
- public String toString() {
- return isNew() ? "New account..." : myServer.getName();
- }
- }
-
protected abstract class ConnectionTask<T> extends CloudConnectionTask<T, SC, DC, SR> {
public ConnectionTask(String title) {
diff --git a/platform/structure-view-api/src/com/intellij/ide/structureView/TextEditorBasedStructureViewModel.java b/platform/structure-view-api/src/com/intellij/ide/structureView/TextEditorBasedStructureViewModel.java
index 5cef3a5801a6..34641fe63557 100644
--- a/platform/structure-view-api/src/com/intellij/ide/structureView/TextEditorBasedStructureViewModel.java
+++ b/platform/structure-view-api/src/com/intellij/ide/structureView/TextEditorBasedStructureViewModel.java
@@ -19,8 +19,8 @@ import com.intellij.ide.util.treeView.smartTree.*;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.event.CaretAdapter;
import com.intellij.openapi.editor.event.CaretEvent;
-import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.util.Disposer;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -71,7 +71,7 @@ public abstract class TextEditorBasedStructureViewModel implements StructureView
myPsiFile = file;
if (editor != null) {
- EditorFactory.getInstance().getEventMulticaster().addCaretListener(new CaretListener() {
+ EditorFactory.getInstance().getEventMulticaster().addCaretListener(new CaretAdapter() {
@Override
public void caretPositionChanged(CaretEvent e) {
if (e.getEditor().equals(myEditor)) {
diff --git a/platform/testFramework/src/com/intellij/mock/Mock.java b/platform/testFramework/src/com/intellij/mock/Mock.java
index d511f2fd2d35..f0ca6a19e745 100644
--- a/platform/testFramework/src/com/intellij/mock/Mock.java
+++ b/platform/testFramework/src/com/intellij/mock/Mock.java
@@ -453,9 +453,10 @@ public class Mock {
throw new UnsupportedOperationException();
}
+ @NotNull
@Override
public String getPath() {
- return null;
+ throw new UnsupportedOperationException();
}
@Override
diff --git a/platform/testFramework/src/com/intellij/mock/MockModule.java b/platform/testFramework/src/com/intellij/mock/MockModule.java
index 9a0065c2115c..e0eaf7aac476 100644
--- a/platform/testFramework/src/com/intellij/mock/MockModule.java
+++ b/platform/testFramework/src/com/intellij/mock/MockModule.java
@@ -1,5 +1,17 @@
/*
- * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
+ * Copyright 2000-2014 JetBrains s.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;
@@ -37,26 +49,31 @@ public class MockModule extends MockComponentManager implements Module {
return "";
}
+ @NotNull
@Override
public GlobalSearchScope getModuleRuntimeScope(final boolean includeTests) {
return new MockGlobalSearchScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleScope() {
return new MockGlobalSearchScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleScope(boolean includeTests) {
return new MockGlobalSearchScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleTestsWithDependentsScope() {
return new MockGlobalSearchScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithDependenciesAndLibrariesScope(final boolean includeTests) {
return new MockGlobalSearchScope();
@@ -64,26 +81,31 @@ public class MockModule extends MockComponentManager implements Module {
//throw new UnsupportedOperationException( "Method getModuleWithDependenciesAndLibrariesScope is not yet implemented in " + getClass().getName());
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithDependenciesScope() {
return new MockGlobalSearchScope();
}
+ @NotNull
@Override
public GlobalSearchScope getModuleContentWithDependenciesScope() {
throw new UnsupportedOperationException("Method getModuleContentWithDependenciesScope is not yet implemented in " + getClass().getName());
}
+ @NotNull
@Override
public GlobalSearchScope getModuleContentScope() {
throw new UnsupportedOperationException("Method getModuleContentScope is not yet implemented in " + getClass().getName());
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithDependentsScope() {
throw new UnsupportedOperationException("Method getModuleWithDependentsScope is not yet implemented in " + getClass().getName());
}
+ @NotNull
@Override
public GlobalSearchScope getModuleWithLibrariesScope() {
throw new UnsupportedOperationException("Method getModuleWithLibrariesScope is not yet implemented in " + getClass().getName());
diff --git a/platform/testFramework/src/com/intellij/mock/MockVirtualFile.java b/platform/testFramework/src/com/intellij/mock/MockVirtualFile.java
index f6c02f5930ee..9f31bbb9b10f 100644
--- a/platform/testFramework/src/com/intellij/mock/MockVirtualFile.java
+++ b/platform/testFramework/src/com/intellij/mock/MockVirtualFile.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.
@@ -90,6 +90,7 @@ public class MockVirtualFile extends VirtualFile {
return ourFileSystem;
}
+ @NotNull
@Override
public String getPath() {
String prefix = myParent == null ? "MOCK_ROOT:" : myParent.getPath();
@@ -101,6 +102,7 @@ public class MockVirtualFile extends VirtualFile {
return myIsWritable;
}
+ @Override
public void setWritable(boolean b) {
myIsWritable = b;
}
diff --git a/platform/testFramework/src/com/intellij/mock/MockVirtualFileSystem.java b/platform/testFramework/src/com/intellij/mock/MockVirtualFileSystem.java
index 2eeee2eb0ac7..19870bfe9b33 100644
--- a/platform/testFramework/src/com/intellij/mock/MockVirtualFileSystem.java
+++ b/platform/testFramework/src/com/intellij/mock/MockVirtualFileSystem.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,9 +113,10 @@ public class MockVirtualFileSystem extends DeprecatedVirtualFileSystem {
@Override
public boolean isDirectory() {
- return myChildren.size() != 0;
+ return !myChildren.isEmpty();
}
+ @NotNull
@Override
public String getPath() {
final MockVirtualFileSystem.MyVirtualFile parent = getParent();
diff --git a/platform/testFramework/testSrc/com/intellij/psi/formatter/FormatterTestCase.java b/platform/testFramework/src/com/intellij/psi/formatter/FormatterTestCase.java
index 2afd09168420..2afd09168420 100644
--- a/platform/testFramework/testSrc/com/intellij/psi/formatter/FormatterTestCase.java
+++ b/platform/testFramework/src/com/intellij/psi/formatter/FormatterTestCase.java
diff --git a/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java
index 5d658bfe7e3a..3ae9b8d1c69b 100644
--- a/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java
+++ b/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java
@@ -30,7 +30,6 @@ import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.editor.impl.DefaultEditorTextRepresentationHelper;
import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
import com.intellij.openapi.editor.impl.softwrap.mapping.SoftWrapApplianceManager;
-import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
@@ -309,13 +308,13 @@ public class EditorTestUtil {
public static void setCaretsAndSelection(Editor editor, CaretAndSelectionState caretsState) {
CaretModel caretModel = editor.getCaretModel();
if (caretModel.supportsMultipleCarets()) {
- List<LogicalPosition> caretPositions = new ArrayList<LogicalPosition>();
- List<Segment> selections = new ArrayList<Segment>();
+ List<CaretState> states = new ArrayList<CaretState>(caretsState.carets.size());
for (CaretInfo caret : caretsState.carets) {
- caretPositions.add(caret.position == null ? null : editor.offsetToLogicalPosition(caret.getCaretOffset(editor.getDocument())));
- selections.add(caret.selection == null ? null : caret.selection);
+ states.add(new CaretState(caret.position == null ? null : editor.offsetToLogicalPosition(caret.getCaretOffset(editor.getDocument())),
+ caret.selection == null ? null : editor.offsetToLogicalPosition(caret.selection.getStartOffset()),
+ caret.selection == null ? null : editor.offsetToLogicalPosition(caret.selection.getEndOffset())));
}
- caretModel.setCaretsAndSelections(caretPositions, selections);
+ caretModel.setCaretsAndSelections(states);
}
else {
assertEquals("Multiple carets are not supported by the model", 1, caretsState.carets.size());
@@ -326,6 +325,9 @@ public class EditorTestUtil {
if (caret.selection != null) {
editor.getSelectionModel().setSelection(caret.selection.getStartOffset(), caret.selection.getEndOffset());
}
+ else {
+ editor.getSelectionModel().removeSelection();
+ }
}
if (caretsState.blockSelection != null) {
editor.getSelectionModel().setBlockSelection(editor.offsetToLogicalPosition(caretsState.blockSelection.getStartOffset()),
diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
index e1e6907985a4..59b8d4b95056 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.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.
@@ -308,14 +308,14 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
protected static Module doCreateRealModuleIn(String moduleName, final Project project, final ModuleType moduleType) {
final VirtualFile baseDir = project.getBaseDir();
assertNotNull(baseDir);
- final File moduleFile = new File(baseDir.getPath().replace('/', File.separatorChar),
- moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION);
+ final File moduleFile = new File(FileUtil.toSystemDependentName(baseDir.getPath()), moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION);
FileUtil.createIfDoesntExist(moduleFile);
myFilesToDelete.add(moduleFile);
return new WriteAction<Module>() {
@Override
- protected void run(Result<Module> result) throws Throwable {
- final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(moduleFile);
+ protected void run(@NotNull Result<Module> result) throws Throwable {
+ VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(moduleFile);
+ assertNotNull(virtualFile);
Module module = ModuleManager.getInstance(project).newModule(virtualFile.getPath(), moduleType.getId());
module.getModuleFile();
result.setResult(module);
diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
index 785c587f488f..104c55e0c77b 100644
--- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
@@ -639,6 +639,14 @@ public abstract class UsefulTestCase extends TestCase {
String actualText = StringUtil.convertLineSeparators(actual.trim());
Assert.assertEquals(expectedText, actualText);
}
+
+ public static void assertExists(File file){
+ assertTrue("File should exists " + file, file.exists());
+ }
+
+ public static void assertDoesntExist(File file){
+ assertFalse("File should not exists " + file, file.exists());
+ }
protected String getTestName(boolean lowercaseFirstLetter) {
String name = getName();
diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java
index 0c24d8b534b4..af4c7f6f35ab 100644
--- a/platform/util/src/com/intellij/icons/AllIcons.java
+++ b/platform/util/src/com/intellij/icons/AllIcons.java
@@ -817,8 +817,11 @@ public class AllIcons {
public static final Icon Parameter = IconLoader.getIcon("/nodes/parameter.png"); // 16x16
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 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
+ public static final Icon PluginUpdate = IconLoader.getIcon("/nodes/pluginUpdate.png"); // 16x16
public static final Icon Pointcut = IconLoader.getIcon("/nodes/pointcut.png"); // 16x16
public static final Icon PpFile = IconLoader.getIcon("/nodes/ppFile.png"); // 16x16
public static final Icon PpInvalid = IconLoader.getIcon("/nodes/ppInvalid.png"); // 16x16
diff --git a/platform/util/src/com/intellij/openapi/diff/LineTokenizer.java b/platform/util/src/com/intellij/openapi/diff/LineTokenizer.java
index 7aafcacf7fbb..e86567bde782 100644
--- a/platform/util/src/com/intellij/openapi/diff/LineTokenizer.java
+++ b/platform/util/src/com/intellij/openapi/diff/LineTokenizer.java
@@ -17,18 +17,14 @@ package com.intellij.openapi.diff;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
-public class LineTokenizer {
+public class LineTokenizer extends LineTokenizerBase<String> {
private final char[] myChars;
private final String myText;
- private int myIndex = 0;
- @Nullable private String myLineSeparator = null;
-
public LineTokenizer(@NotNull String text) {
myChars = text.toCharArray();
myText = text;
@@ -36,71 +32,35 @@ public class LineTokenizer {
@NotNull
public String[] execute() {
- List<String> lines = new ArrayList<String>();
- while (notAtEnd()) {
- int begin = myIndex;
- skipToEOL();
- int endIndex = myIndex;
- boolean appendNewLine = false;
-
- if (notAtEnd() && isAtEOL()) {
- if (myChars[endIndex] == '\n') {
- endIndex++;
- }
- else {
- appendNewLine = true;
- }
- skipEOL();
- }
-
- String line = myText.substring(begin, endIndex);
- if (appendNewLine) {
- line += "\n";
- }
- lines.add(line);
- }
+ ArrayList<String> lines = new ArrayList<String>();
+ doExecute(lines);
return ArrayUtil.toStringArray(lines);
}
- private void skipEOL() {
- int eolStart = myIndex;
- boolean nFound = false;
- boolean rFound = false;
- while (notAtEnd()) {
- boolean n = myChars[myIndex] == '\n';
- boolean r = myChars[myIndex] == '\r';
- if (!n && !r) {
- break;
- }
- if ((nFound && n) || (rFound && r)) {
- break;
- }
- nFound |= n;
- rFound |= r;
- myIndex++;
+ @Override
+ protected void addLine(List<String> lines, int start, int end, boolean appendNewLine) {
+ if (appendNewLine) {
+ lines.add(myText.substring(start, end) + "\n");
}
- if (myLineSeparator == null) {
- myLineSeparator = new String(myChars, eolStart, myIndex - eolStart);
+ else {
+ lines.add(myText.substring(start, end));
}
}
- @Nullable
- public String getLineSeparator() {
- return myLineSeparator;
+ @Override
+ protected char charAt(int index) {
+ return myChars[index];
}
- private void skipToEOL() {
- while (notAtEnd() && !isAtEOL()) {
- myIndex++;
- }
- }
-
- private boolean notAtEnd() {
- return myIndex < myChars.length;
+ @Override
+ protected int length() {
+ return myChars.length;
}
- private boolean isAtEOL() {
- return myChars[myIndex] == '\r' || myChars[myIndex] == '\n';
+ @NotNull
+ @Override
+ protected String substring(int start, int end) {
+ return myText.substring(start, end);
}
@NotNull
diff --git a/platform/util/src/com/intellij/openapi/diff/LineTokenizerBase.java b/platform/util/src/com/intellij/openapi/diff/LineTokenizerBase.java
new file mode 100644
index 000000000000..85fed352e819
--- /dev/null
+++ b/platform/util/src/com/intellij/openapi/diff/LineTokenizerBase.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.diff;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+public abstract class LineTokenizerBase<T> {
+ private int myIndex = 0;
+ private int myLineSeparatorStart = -1;
+ private int myLineSeparatorEnd = -1;
+
+ protected abstract void addLine(List<T> lines, int start, int end, boolean appendNewLine);
+
+ protected abstract char charAt(int index);
+
+ protected abstract int length();
+
+ @NotNull
+ protected abstract String substring(int start, int end);
+
+ public void doExecute(List<T> lines) {
+ while (notAtEnd()) {
+ int begin = myIndex;
+ skipToEOL();
+ int endIndex = myIndex;
+ boolean appendNewLine = false;
+
+ if (notAtEnd() && isAtEOL()) {
+ if (charAt(endIndex) == '\n') {
+ endIndex++;
+ }
+ else {
+ appendNewLine = true;
+ }
+ skipEOL();
+ }
+
+ addLine(lines, begin, endIndex, appendNewLine);
+ }
+ }
+
+ private void skipEOL() {
+ int eolStart = myIndex;
+ boolean nFound = false;
+ boolean rFound = false;
+ while (notAtEnd()) {
+ boolean n = charAt(myIndex) == '\n';
+ boolean r = charAt(myIndex) == '\r';
+ if (!n && !r) {
+ break;
+ }
+ if ((nFound && n) || (rFound && r)) {
+ break;
+ }
+ nFound |= n;
+ rFound |= r;
+ myIndex++;
+ }
+ if (myLineSeparatorStart == -1) {
+ myLineSeparatorStart = eolStart;
+ myLineSeparatorEnd = myIndex;
+ }
+ }
+
+ @Nullable
+ public String getLineSeparator() {
+ if (myLineSeparatorStart == -1) return null;
+ return substring(myLineSeparatorStart, myLineSeparatorEnd);
+ }
+
+ private void skipToEOL() {
+ while (notAtEnd() && !isAtEOL()) {
+ myIndex++;
+ }
+ }
+
+ private boolean notAtEnd() {
+ return myIndex < length();
+ }
+
+ private boolean isAtEOL() {
+ return charAt(myIndex) == '\r' || charAt(myIndex) == '\n';
+ }
+} \ No newline at end of file
diff --git a/platform/util/src/com/intellij/openapi/diff/ex/DiffFragment.java b/platform/util/src/com/intellij/openapi/diff/ex/DiffFragment.java
index 791d4a0c46e1..e1a4852affe0 100644
--- a/platform/util/src/com/intellij/openapi/diff/ex/DiffFragment.java
+++ b/platform/util/src/com/intellij/openapi/diff/ex/DiffFragment.java
@@ -15,31 +15,37 @@
*/
package com.intellij.openapi.diff.ex;
+import com.intellij.openapi.diff.impl.string.DiffString;
+import com.intellij.openapi.diff.impl.string.DiffStringBuilder;
import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
public class DiffFragment {
public static DiffFragment[] EMPTY_ARRAY = new DiffFragment[0];
- private final String myText1;
- private final String myText2;
+ @Nullable private CharSequence myText1;
+ @Nullable private CharSequence myText2;
private boolean myIsModified;
- private StringBuilder myText1Builder;
- private StringBuilder myText2Builder;
+ @TestOnly
+ public DiffFragment(@Nullable String text1, @Nullable String text2) {
+ this(DiffString.createNullable(text1), DiffString.createNullable(text2));
+ }
- public DiffFragment(String text1, String text2) {
+ public DiffFragment(@Nullable DiffString text1, @Nullable DiffString text2) {
myText1 = text1;
myText2 = text2;
myIsModified = (text1 == null || text2 == null || !text1.equals(text2));
}
- public static boolean isEmpty(DiffFragment fragment) {
- return StringUtil.length(fragment.getText1()) == 0 &&
- StringUtil.length(fragment.getText2()) == 0;
+ public boolean isEmpty() {
+ return StringUtil.isEmpty(myText1) && StringUtil.isEmpty(myText2);
}
/**
- * Makes sence if both texts are not null
+ * Makes sense if both texts are not null
* @return true if both texts are considered modified, false otherwise
*/
public boolean isModified() {
@@ -50,34 +56,70 @@ public class DiffFragment {
myIsModified = modified;
}
- public void appendText1(String str) {
- assert myText1 != null;
- if (myText1Builder == null) {
- myText1Builder = new StringBuilder(myText1);
+ public void appendText1(@Nullable DiffString str) {
+ if (str == null) return;
+ if (myText1 instanceof DiffStringBuilder) {
+ ((DiffStringBuilder)myText1).append(str);
+ return;
+ }
+
+ if (myText1 instanceof DiffString) {
+ DiffString text1 = (DiffString)myText1;
+ if (DiffString.canInplaceConcatenate(text1, str)) {
+ myText1 = DiffString.concatenate(text1, str);
+ }
+ else {
+ DiffStringBuilder builder = new DiffStringBuilder(text1.length() + str.length());
+ builder.append(text1);
+ builder.append(str);
+ myText1 = builder;
+ }
+ return;
}
- myText1Builder.append(str);
+
+ throw new IllegalStateException("Bad DiffFragment: " + (myText1 != null ? myText1.getClass() : "null"));
}
- public void appendText2(String str) {
- assert myText2 != null;
- if (myText2Builder == null) {
- myText2Builder = new StringBuilder(myText2);
+ public void appendText2(@Nullable DiffString str) {
+ if (str == null) return;
+ if (myText2 instanceof DiffStringBuilder) {
+ ((DiffStringBuilder)myText2).append(str);
+ return;
}
- myText2Builder.append(str);
+
+ if (myText2 instanceof DiffString) {
+ DiffString text2 = (DiffString)myText2;
+ if (DiffString.canInplaceConcatenate(text2, str)) {
+ myText2 = DiffString.concatenate(text2, str);
+ }
+ else {
+ DiffStringBuilder builder = new DiffStringBuilder(text2.length() + str.length());
+ builder.append(text2);
+ builder.append(str);
+ myText2 = builder;
+ }
+ return;
+ }
+
+ throw new IllegalStateException("Bad DiffFragment: " + (myText2 != null ? myText2.getClass() : "null"));
}
- /**
- * null if absent
- */
- public String getText1() {
- return myText1Builder != null ? myText1Builder.toString() : myText1;
+ @Nullable
+ public DiffString getText1() {
+ if (myText1 == null) return null;
+ if (myText1 instanceof DiffString) return (DiffString)myText1;
+ if (myText1 instanceof DiffStringBuilder) return ((DiffStringBuilder)myText1).toDiffString();
+
+ throw new IllegalStateException("Bad DiffFragment: " + myText1.getClass());
}
-
- /**
- * null if absent
- */
- public String getText2() {
- return myText2Builder != null ? myText2Builder.toString() : myText2;
+
+ @Nullable
+ public DiffString getText2() {
+ if (myText2 == null) return null;
+ if (myText2 instanceof DiffString) return (DiffString)myText2;
+ if (myText2 instanceof DiffStringBuilder) return ((DiffStringBuilder)myText2).toDiffString();
+
+ throw new IllegalStateException("Bad DiffFragment: " + myText2.getClass());
}
/**
@@ -85,23 +127,30 @@ public class DiffFragment {
* @return true iff both texts are present and {@link #isModified()}
*/
public boolean isChange() {
- return myText1 != null && myText2 != null && isModified();
+ return (myText1 != null) && (myText2 != null) && isModified();
}
/**
* @return true iff both texts are present and not {@link #isModified()}
*/
public boolean isEqual() {
- return myText1 != null && myText2 != null && !isModified();
+ return (myText1 != null) && (myText2 != null) && !isModified();
+ }
+
+ @TestOnly
+ public static DiffFragment unchanged(@Nullable String text1, @Nullable String text2) {
+ return unchanged(DiffString.createNullable(text1), DiffString.createNullable(text2));
}
- public static DiffFragment unchanged(String text1, String text2) {
+ public static DiffFragment unchanged(@Nullable DiffString text1, @Nullable DiffString text2) {
+ if (text1 == null) text1 = DiffString.EMPTY;
+ if (text2 == null) text2 = DiffString.EMPTY;
DiffFragment result = new DiffFragment(text1, text2);
result.setModified(false);
return result;
}
public boolean isOneSide() {
- return myText1 == null || myText2 == null;
+ return (myText1 == null) || (myText2 == null);
}
}
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/ComparisonPolicy.java b/platform/util/src/com/intellij/openapi/diff/impl/ComparisonPolicy.java
index 0767413e3f5b..b38c827adf9f 100644
--- a/platform/util/src/com/intellij/openapi/diff/impl/ComparisonPolicy.java
+++ b/platform/util/src/com/intellij/openapi/diff/impl/ComparisonPolicy.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.diff.impl;
import com.intellij.CommonBundle;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
import com.intellij.openapi.diff.impl.highlighting.Util;
@@ -24,18 +25,30 @@ import com.intellij.openapi.diff.impl.processing.Formatting;
import com.intellij.openapi.diff.impl.processing.Word;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.diff.Diff;
import com.intellij.util.diff.FilesTooBigForDiffException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
public abstract class ComparisonPolicy {
+ public static final ComparisonPolicy DEFAULT = new DefaultPolicy();
+ public static final ComparisonPolicy TRIM_SPACE = new TrimSpacePolicy();
+ public static final ComparisonPolicy IGNORE_SPACE = new IgnoreSpacePolicy();
+ public static final ComparisonPolicy[] COMPARISON_POLICIES = new ComparisonPolicy[]{DEFAULT, IGNORE_SPACE, TRIM_SPACE};
+
private final String myName;
protected ComparisonPolicy(final String name) {
myName = name;
}
- public DiffFragment[] buildFragments(String[] strings1, String[] strings2) throws FilesTooBigForDiffException {
+ public String getName() {
+ return myName;
+ }
+
+ @NotNull
+ public DiffFragment[] buildFragments(@NotNull DiffString[] strings1, @NotNull DiffString[] strings2) throws FilesTooBigForDiffException {
DiffFragmentBuilder builder = new DiffFragmentBuilder(strings1, strings2);
Object[] wrappers1 = getWrappers(strings1);
Object[] wrappers2 = getWrappers(strings2);
@@ -43,7 +56,9 @@ public abstract class ComparisonPolicy {
return builder.buildFragments(Util.concatEquals(change, wrappers1, wrappers2));
}
- public DiffFragment[] buildDiffFragmentsFromLines(String[] lines1, String[] lines2) throws FilesTooBigForDiffException {
+ @NotNull
+ public DiffFragment[] buildDiffFragmentsFromLines(@NotNull DiffString[] lines1, @NotNull DiffString[] lines2)
+ throws FilesTooBigForDiffException {
DiffFragmentBuilder builder = new DiffFragmentBuilder(lines1, lines2);
Object[] wrappers1 = getLineWrappers(lines1);
Object[] wrappers2 = getLineWrappers(lines2);
@@ -51,19 +66,52 @@ public abstract class ComparisonPolicy {
return builder.buildFragments(change);
}
- public static final ComparisonPolicy DEFAULT = new ComparisonPolicy(CommonBundle.message("comparison.policy.default.name")) {
+ @NotNull
+ public DiffFragment createFragment(@Nullable DiffString text1, @Nullable DiffString text2) {
+ text1 = toNull(text1);
+ text2 = toNull(text2);
+ if (text1 == null && text2 == null) return new DiffFragment(DiffString.EMPTY, DiffString.EMPTY);
+ DiffFragment result = new DiffFragment(text1, text2);
+ if (text1 != null && text2 != null) {
+ result.setModified(!getWrapper(text1).equals(getWrapper(text2)));
+ }
+ return result;
+ }
+
+ @NotNull
+ public abstract DiffFragment createFragment(@NotNull Word word1, @NotNull Word word2);
+
+ @NotNull
+ protected abstract Object[] getWrappers(@NotNull DiffString[] strings);
+
+ @NotNull
+ protected abstract Object[] getLineWrappers(@NotNull DiffString[] lines);
+
+ @NotNull
+ private Object getWrapper(@NotNull DiffString text) {
+ return getWrappers(new DiffString[]{text})[0];
+ }
+
+ private static class DefaultPolicy extends ComparisonPolicy {
+ public DefaultPolicy() {
+ super(CommonBundle.message("comparison.policy.default.name"));
+ }
+
+ @NotNull
@Override
- protected Object[] getWrappers(String[] strings) {
+ protected Object[] getWrappers(@NotNull DiffString[] strings) {
return strings;
}
+ @NotNull
@Override
- protected Object[] getLineWrappers(String[] lines) {
+ protected Object[] getLineWrappers(@NotNull DiffString[] lines) {
return lines;
}
+ @NotNull
@Override
- public DiffFragment createFragment(Word word1, Word word2) {
+ public DiffFragment createFragment(@NotNull Word word1, @NotNull Word word2) {
return createFragment(word1.getText(), word2.getText());
}
@@ -71,18 +119,24 @@ public abstract class ComparisonPolicy {
public String toString() {
return "DEFAULT";
}
- };
+ }
+
+ private static class TrimSpacePolicy extends ComparisonPolicy {
+ public TrimSpacePolicy() {
+ super(CommonBundle.message("comparison.policy.trim.space.name"));
+ }
- public static final ComparisonPolicy TRIM_SPACE = new ComparisonPolicy(CommonBundle.message("comparison.policy.trim.space.name")) {
+ @NotNull
@Override
- protected Object[] getLineWrappers(String[] lines) {
+ protected Object[] getLineWrappers(@NotNull DiffString[] lines) {
return trimStrings(lines);
}
+ @NotNull
@Override
- public DiffFragment createFragment(Word word1, Word word2) {
- String text1 = word1.getText();
- String text2 = word2.getText();
+ public DiffFragment createFragment(@NotNull Word word1, @NotNull Word word2) {
+ DiffString text1 = word1.getText();
+ DiffString text2 = word2.getText();
if (word1.isWhitespace() && word2.isWhitespace() &&
word1.atEndOfLine() && word2.atEndOfLine()) {
return DiffFragment.unchanged(text1, text2);
@@ -90,16 +144,17 @@ public abstract class ComparisonPolicy {
return createFragment(text1, text2);
}
+ @NotNull
@Override
- protected Object[] getWrappers(String[] strings) {
+ protected Object[] getWrappers(@NotNull DiffString[] strings) {
Object[] result = new Object[strings.length];
boolean atBeginning = true;
for (int i = 0; i < strings.length; i++) {
- String string = strings[i];
- String wrapper = atBeginning ? StringUtil.trimLeading(string) : string;
- if (StringUtil.endsWithChar(wrapper, '\n')) {
+ DiffString string = strings[i];
+ DiffString wrapper = atBeginning ? string.trimLeading() : string;
+ if (wrapper.endsWith('\n')) {
atBeginning = true;
- wrapper = StringUtil.trimTrailing(wrapper);
+ wrapper = wrapper.trimTrailing();
}
else {
atBeginning = false;
@@ -109,128 +164,66 @@ public abstract class ComparisonPolicy {
return result;
}
-
-
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
return "TRIM";
}
- };
-
- public static final ComparisonPolicy IGNORE_SPACE = new IgnoreSpacePolicy();
-
- private static String toNotNull(String text) {
- return text == null ? "" : text;
}
- protected abstract Object[] getWrappers(String[] strings);
-
- protected abstract Object[] getLineWrappers(String[] lines);
-
- protected Object[] trimStrings(String[] strings) {
- Object[] result = new Object[strings.length];
- for (int i = 0; i < strings.length; i++) {
- String string = strings[i];
- result[i] = string.trim();
- }
- return result;
- }
-
- public DiffFragment createFragment(String text1, String text2) {
- text1 = toNull(text1);
- text2 = toNull(text2);
- if (text1 == null && text2 == null) return new DiffFragment("", "");
- DiffFragment result = new DiffFragment(text1, text2);
- if (text1 != null && text2 != null) {
- result.setModified(!getWrapper(text1).equals(getWrapper(text2)));
- }
- return result;
- }
-
- private String toNull(String text1) {
- return text1 == null || text1.isEmpty() ? null : text1;
- }
-
- private Object getWrapper(String text) {
- return getWrappers(new String[]{text})[0];
- }
-
- public boolean isEqual(DiffFragment fragment) {
- if (fragment.isOneSide()) return false;
- Object[] wrappers = getLineWrappers(new String[]{fragment.getText1(), fragment.getText2()});
- return Comparing.equal(wrappers[0], wrappers[1]);
- }
-
- public Word createFormatting(String text, TextRange textRange) {
- return new Formatting(text, textRange);
- }
-
- public abstract DiffFragment createFragment(Word word1, Word word2);
-
- public String getName() {
- return myName;
- }
-
- public static final ComparisonPolicy[] COMPARISON_POLICIES = new ComparisonPolicy[]{DEFAULT, IGNORE_SPACE, TRIM_SPACE};
-
- public static ComparisonPolicy[] getAllInstances() {
- return COMPARISON_POLICIES;
- }
-
- private static class IgnoreSpacePolicy extends ComparisonPolicy implements DiffCorrection.FragmentProcessor<DiffCorrection.FragmentsCollector> {
+ private static class IgnoreSpacePolicy extends ComparisonPolicy
+ implements DiffCorrection.FragmentProcessor<DiffCorrection.FragmentsCollector> {
public IgnoreSpacePolicy() {
super(CommonBundle.message("comparison.policy.ignore.spaces.name"));
}
+ @NotNull
@Override
- protected Object[] getLineWrappers(String[] lines) {
+ protected Object[] getLineWrappers(@NotNull DiffString[] lines) {
Object[] result = new Object[lines.length];
for (int i = 0; i < lines.length; i++) {
- String line = lines[i];
+ DiffString line = lines[i];
result[i] = getWrapper(line);
}
return result;
}
+ @NotNull
@Override
- public DiffFragment[] buildFragments(String[] strings1, String[] strings2) throws FilesTooBigForDiffException {
+ public DiffFragment[] buildFragments(@NotNull DiffString[] strings1, @NotNull DiffString[] strings2)
+ throws FilesTooBigForDiffException {
DiffFragment[] fragments = super.buildFragments(strings1, strings2);
DiffCorrection.FragmentsCollector collector = new DiffCorrection.FragmentsCollector();
collector.processAll(fragments, this);
return collector.toArray();
}
- private Object getWrapper(String line) {
- StringBuilder builder = new StringBuilder(line.length());
- for (int i = 0; i < line.length(); i++) {
- char aChar = line.charAt(i);
- if (StringUtil.isWhiteSpace(aChar)) continue;
- builder.append(aChar);
- }
- return builder.toString();
+ @NotNull
+ private static Object getWrapper(@NotNull DiffString line) {
+ return line.skipSpaces();
}
+ @NotNull
@Override
- public DiffFragment createFragment(Word word1, Word word2) {
- String text1 = word1.getText();
- String text2 = word2.getText();
- return word1.isWhitespace() && word2.isWhitespace() ?
- DiffFragment.unchanged(text1, text2) :
- createFragment(text1, text2);
+ public DiffFragment createFragment(@NotNull Word word1, @NotNull Word word2) {
+ DiffString text1 = word1.getText();
+ DiffString text2 = word2.getText();
+ return word1.isWhitespace() && word2.isWhitespace() ? DiffFragment.unchanged(text1, text2) : createFragment(text1, text2);
}
+ @NotNull
@Override
- public DiffFragment createFragment(String text1, String text2) {
- String toCompare1 = toNotNull(text1);
- String toCompare2 = toNotNull(text2);
+ public DiffFragment createFragment(DiffString text1, DiffString text2) {
+ DiffString toCompare1 = toNotNull(text1);
+ DiffString toCompare2 = toNotNull(text2);
if (getWrapper(toCompare1).equals(getWrapper(toCompare2))) {
return DiffFragment.unchanged(toCompare1, toCompare2);
}
return new DiffFragment(text1, text2);
}
+ @NotNull
@Override
- protected Object[] getWrappers(String[] strings) {
+ protected Object[] getWrappers(@NotNull DiffString[] strings) {
return trimStrings(strings);
}
@@ -240,21 +233,76 @@ public abstract class ComparisonPolicy {
}
@Override
- public void process(DiffFragment fragment, DiffCorrection.FragmentsCollector collector) {
+ public void process(@NotNull DiffFragment fragment, @NotNull DiffCorrection.FragmentsCollector collector) {
if (fragment.isEqual()) {
collector.add(fragment);
return;
}
if (fragment.isOneSide()) {
FragmentSide side = FragmentSide.chooseSide(fragment);
- String text = side.getText(fragment);
- String trimed = text.trim();
+ DiffString text = side.getText(fragment);
+ DiffString trimed = text.trim();
if (trimed.isEmpty()) {
- collector.add(side.createFragment(text, "", false));
+ collector.add(side.createFragment(text, DiffString.EMPTY, false));
return;
}
}
collector.add(fragment);
}
}
+
+ @Nullable
+ private static DiffString toNull(@Nullable DiffString text1) {
+ return text1 == null || text1.isEmpty() ? null : text1;
+ }
+
+ @NotNull
+ private static DiffString toNotNull(@Nullable DiffString text) {
+ return text == null ? DiffString.EMPTY : text;
+ }
+
+ @NotNull
+ protected Object[] trimStrings(@NotNull DiffString[] strings) {
+ Object[] result = new Object[strings.length];
+ for (int i = 0; i < strings.length; i++) {
+ DiffString string = strings[i];
+ result[i] = string.trim();
+ }
+ return result;
+ }
+
+ public boolean isEqual(@NotNull DiffFragment fragment) {
+ if (fragment.isOneSide()) return false;
+ Object[] wrappers = getLineWrappers(new DiffString[]{fragment.getText1(), fragment.getText2()});
+ return Comparing.equal(wrappers[0], wrappers[1]);
+ }
+
+ @NotNull
+ public Word createFormatting(@NotNull DiffString text, @NotNull TextRange textRange) {
+ return new Formatting(text, textRange);
+ }
+
+ public static ComparisonPolicy[] getAllInstances() {
+ return COMPARISON_POLICIES;
+ }
+
+ @NotNull
+ @TestOnly
+ protected Object[] getWrappers(@NotNull String[] lines) {
+ DiffString[] unsafeStrings = new DiffString[lines.length];
+ for (int i = 0; i < lines.length; i++) {
+ unsafeStrings[i] = DiffString.createNullable(lines[i]);
+ }
+ return getWrappers(unsafeStrings);
+ }
+
+ @NotNull
+ @TestOnly
+ protected Object[] getLineWrappers(@NotNull String[] lines) {
+ DiffString[] unsafeStrings = new DiffString[lines.length];
+ for (int i = 0; i < lines.length; i++) {
+ unsafeStrings[i] = DiffString.createNullable(lines[i]);
+ }
+ return getLineWrappers(unsafeStrings);
+ }
}
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/DiffFragmentBuilder.java b/platform/util/src/com/intellij/openapi/diff/impl/DiffFragmentBuilder.java
index 3b6a00b16fb9..64630e981753 100644
--- a/platform/util/src/com/intellij/openapi/diff/impl/DiffFragmentBuilder.java
+++ b/platform/util/src/com/intellij/openapi/diff/impl/DiffFragmentBuilder.java
@@ -21,9 +21,12 @@
package com.intellij.openapi.diff.impl;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.util.TextRange;
import com.intellij.util.diff.Diff;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.LinkedList;
import java.util.List;
@@ -56,25 +59,26 @@ public class DiffFragmentBuilder {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.DiffFragmentBuilder");
- private final String[] mySource1;
- private final String[] mySource2;
+ @NotNull private final DiffString[] mySource1;
+ @NotNull private final DiffString[] mySource2;
private int myLastLine1 = 1;
private int myLastLine2 = 1;
- private final List<DiffFragment> myData = new LinkedList<DiffFragment>();
+ @NotNull private final List<DiffFragment> myData = new LinkedList<DiffFragment>();
- public DiffFragmentBuilder(String[] source1, String[] source2) {
+ public DiffFragmentBuilder(@NotNull DiffString[] source1, @NotNull DiffString[] source2) {
mySource1 = source1;
mySource2 = source2;
init();
}
+ @NotNull
private List<DiffFragment> getFragments() {
return myData;
}
private void finish() {
- String text1 = null;
- String text2 = null;
+ DiffString text1 = null;
+ DiffString text2 = null;
if (myLastLine1 <= mySource1.length) {
text1 = concatenate(mySource1, myLastLine1, mySource1.length);
}
@@ -91,10 +95,10 @@ public class DiffFragmentBuilder {
myLastLine1 = myLastLine2 = 1;
}
- private void append(int line, TextRange range) {
+ private void append(int line, @NotNull TextRange range) {
LOG.debug("DiffFragmentBuilder.append(" + line + "," + range + "), modified:");
- String text1 = null;
- String text2 = null;
+ DiffString text1 = null;
+ DiffString text2 = null;
int start = range.getStartOffset();
int end = range.getEndOffset();
if (myLastLine1 <= line) {
@@ -111,10 +115,10 @@ public class DiffFragmentBuilder {
myLastLine2 = end + 1;
}
- private void change(TextRange range1, TextRange range2) {
+ private void change(@NotNull TextRange range1, @NotNull TextRange range2) {
LOG.debug("DiffFragmentBuilder.change(" + range1 + "," + range2 + ")");
- String text1 = null, text2 = null;
+ DiffString text1 = null, text2 = null;
int start1 = range1.getStartOffset();
int end1 = range1.getEndOffset();
int start2 = range2.getStartOffset();
@@ -134,11 +138,11 @@ public class DiffFragmentBuilder {
myLastLine2 = end2 + 1;
}
- private void delete(TextRange range, int line) {
+ private void delete(@NotNull TextRange range, int line) {
LOG.debug("DiffFragmentBuilder.delete(" + range + "," + line + ")");
- String text1 = null;
- String text2 = null;
+ DiffString text1 = null;
+ DiffString text2 = null;
int start = range.getStartOffset();
int end = range.getEndOffset();
if (myLastLine1 < start) {
@@ -155,15 +159,13 @@ public class DiffFragmentBuilder {
myLastLine2 = line + 1;
}
- private static String concatenate(String[] strings, int start, int end) {
- int len = 0;
- for (int i = start - 1; i < end; i++) len += strings[i] == null ? 0 : strings[i].length();
- StringBuilder buffer = new StringBuilder(len);
- for (int i = start - 1; i < end; i++) buffer.append(strings[i]);
- return buffer.toString();
+ @NotNull
+ private static DiffString concatenate(@NotNull DiffString[] strings, int start, int end) {
+ return DiffString.concatenate(strings, start - 1, end - start + 1);
}
- public DiffFragment[] buildFragments(Diff.Change change) {
+ @NotNull
+ public DiffFragment[] buildFragments(@Nullable Diff.Change change) {
while (change != null) {
if (change.inserted > 0 && change.deleted > 0) {
change(
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/fragments/LineFragment.java b/platform/util/src/com/intellij/openapi/diff/impl/fragments/LineFragment.java
index 705be4f7ad1e..57399b5b4220 100644
--- a/platform/util/src/com/intellij/openapi/diff/impl/fragments/LineFragment.java
+++ b/platform/util/src/com/intellij/openapi/diff/impl/fragments/LineFragment.java
@@ -16,10 +16,12 @@
package com.intellij.openapi.diff.impl.fragments;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
import com.intellij.openapi.diff.impl.util.TextDiffTypeEnum;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -147,9 +149,10 @@ public class LineFragment extends LineBlock implements Fragment {
return myChildren == null || myChildren.isEmpty() ? null : myChildren.iterator();
}
- public String getText(String text, FragmentSide side) {
+ @NotNull
+ public DiffString getText(@NotNull DiffString text, @NotNull FragmentSide side) {
TextRange range = getRange(side);
- return range.substring(text);
+ return text.substring(range.getStartOffset(), range.getEndOffset());
}
@@ -186,7 +189,7 @@ public class LineFragment extends LineBlock implements Fragment {
}
boolean hasLineChildren = false;
boolean hasInlineChildren = false;
- for (; iterator.hasNext();) {
+ while(iterator.hasNext()) {
Fragment fragment = iterator.next();
boolean lineChild = fragment instanceof LineFragment;
hasLineChildren |= lineChild;
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/highlighting/FragmentSide.java b/platform/util/src/com/intellij/openapi/diff/impl/highlighting/FragmentSide.java
index 620a8f3e0f55..efdf58937db5 100644
--- a/platform/util/src/com/intellij/openapi/diff/impl/highlighting/FragmentSide.java
+++ b/platform/util/src/com/intellij/openapi/diff/impl/highlighting/FragmentSide.java
@@ -16,19 +16,23 @@
package com.intellij.openapi.diff.impl.highlighting;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
public enum FragmentSide {
SIDE1(0, 0) {
@Override
- public String getText(DiffFragment fragment) {
+ @Nullable
+ public DiffString getText(@NotNull DiffFragment fragment) {
return fragment.getText1();
}
@Override
- protected DiffFragment createDiffFragment(String text, String otherText) {
+ @NotNull
+ protected DiffFragment createDiffFragment(@Nullable DiffString text, @Nullable DiffString otherText) {
return new DiffFragment(text, otherText);
}
@@ -40,12 +44,14 @@ public enum FragmentSide {
SIDE2(1, 2) {
@Override
- public String getText(DiffFragment fragment) {
+ @Nullable
+ public DiffString getText(@NotNull DiffFragment fragment) {
return fragment.getText2();
}
@Override
- protected DiffFragment createDiffFragment(String text, String otherText) {
+ @NotNull
+ protected DiffFragment createDiffFragment(@Nullable DiffString text, @Nullable DiffString otherText) {
return new DiffFragment(otherText, text);
}
@@ -65,15 +71,18 @@ public enum FragmentSide {
myMergeIndex = mergeIndex;
}
- public DiffFragment createFragment(String text, String otherText, boolean modified) {
+ @NotNull
+ public DiffFragment createFragment(@Nullable DiffString text, @Nullable DiffString otherText, boolean modified) {
DiffFragment fragment = createDiffFragment(text, otherText);
if (!fragment.isOneSide()) fragment.setModified(modified);
return fragment;
}
- public abstract String getText(DiffFragment fragment);
+ @Nullable
+ public abstract DiffString getText(@NotNull DiffFragment fragment);
public abstract FragmentSide otherSide();
- protected abstract DiffFragment createDiffFragment(String text, String otherText);
+ @NotNull
+ protected abstract DiffFragment createDiffFragment(@Nullable DiffString text, @Nullable DiffString otherText);
public int getIndex() {
return myIndex;
@@ -83,7 +92,8 @@ public enum FragmentSide {
return myMergeIndex;
}
- public String getOtherText(DiffFragment fragment) {
+ @Nullable
+ public DiffString getOtherText(@NotNull DiffFragment fragment) {
return otherSide().getText(fragment);
}
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/highlighting/Util.java b/platform/util/src/com/intellij/openapi/diff/impl/highlighting/Util.java
index 83cfa988c573..15c24d364118 100644
--- a/platform/util/src/com/intellij/openapi/diff/impl/highlighting/Util.java
+++ b/platform/util/src/com/intellij/openapi/diff/impl/highlighting/Util.java
@@ -16,11 +16,14 @@
package com.intellij.openapi.diff.impl.highlighting;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.diff.Diff;
import gnu.trove.TIntHashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
@@ -33,14 +36,15 @@ public class Util {
public static final TIntHashSet DELIMITERS_SET = new TIntHashSet();
static {
- char[] delimiters = Util.DELIMITERS.toCharArray();
+ char[] delimiters = DELIMITERS.toCharArray();
for (int i = 0; i < delimiters.length; i++) {
char delimiter = delimiters[i];
- Util.DELIMITERS_SET.add(delimiter);
+ DELIMITERS_SET.add(delimiter);
}
}
- static String[] splitByWord(String string) {
+ @NotNull
+ static String[] splitByWord(@NotNull String string) {
BufferedStringList stringList = new BufferedStringList();
StringTokenizer tokenizer = new StringTokenizer(string, DELIMITERS, true);
while (tokenizer.hasMoreTokens()) {
@@ -62,19 +66,19 @@ public class Util {
return stringList.toArray();
}
- static boolean isSpaceOnly(DiffFragment fragment) {
+ static boolean isSpaceOnly(@NotNull DiffFragment fragment) {
return isSpaceOnly(fragment.getText1()) && isSpaceOnly(fragment.getText2());
}
- private static boolean isSpaceOnly(String string) {
+ private static boolean isSpaceOnly(@Nullable DiffString string) {
if (string == null) return true;
- for (int i = 0; i < string.length(); i++) if (!Character.isWhitespace(string.charAt(i))) return false;
- return true;
+ return string.isEmptyOrSpaces();
}
- static DiffFragment[] splitByLines(DiffFragment fragment) {
- String[] lines1 = splitByLines(fragment.getText1());
- String[] lines2 = splitByLines(fragment.getText2());
+ @NotNull
+ static DiffFragment[] splitByLines(@NotNull DiffFragment fragment) {
+ DiffString[] lines1 = splitByLines(fragment.getText1());
+ DiffString[] lines2 = splitByLines(fragment.getText2());
if (lines1 != null && lines2 != null && lines1.length != lines2.length) {
LOG.error("1:<" + fragment.getText1() + "> 2:<" + fragment.getText2() + ">");
}
@@ -86,22 +90,16 @@ public class Util {
return lines;
}
- private static String[] splitByLines(String string) {
+ @Nullable
+ private static DiffString[] splitByLines(@Nullable DiffString string) {
if (string == null) return null;
- if (string.indexOf('\n') == -1) return new String[]{string};
- String[] strings = string.split("\n", -1);
- for (int i = 0; i < strings.length - 1; i++) {
- strings[i] += "\n";
- }
- if (StringUtil.endsWithChar(string, '\n')) {
- String[] result = new String[strings.length - 1];
- System.arraycopy(strings, 0, result, 0, strings.length - 1);
- return result;
- }
- return strings;
+ if (string.indexOf('\n') == -1) return new DiffString[]{string};
+
+ return string.tokenize();
}
- public static DiffFragment[][] splitByUnchangedLines(DiffFragment[] fragments) {
+ @NotNull
+ public static DiffFragment[][] splitByUnchangedLines(@NotNull DiffFragment[] fragments) {
List2D result = new List2D();
for (int i = 0; i < fragments.length; i++) {
DiffFragment fragment = fragments[i];
@@ -109,8 +107,10 @@ public class Util {
result.add(fragment);
continue;
}
- String text1 = fragment.getText1();
- String text2 = fragment.getText2();
+ DiffString text1 = fragment.getText1();
+ DiffString text2 = fragment.getText2();
+ assert text1 != null;
+ assert text2 != null;
if (StringUtil.endsWithChar(text1, '\n') && StringUtil.endsWithChar(text2, '\n')) {
result.add(fragment);
result.newRow();
@@ -139,7 +139,7 @@ public class Util {
return result.toArray();
}
- public static Diff.Change concatEquals(Diff.Change change, Object[] left, Object[] right) {
+ public static Diff.Change concatEquals(Diff.Change change, @NotNull Object[] left, @NotNull Object[] right) {
MyChange startChange = new MyChange(0, 0, 0, 0);
MyChange lastChange = startChange;
while (change != null) {
@@ -187,7 +187,7 @@ public class Util {
return startChange.link;
}
- static int calcShift(Object[] list, int limit, int start, int length) {
+ static int calcShift(@NotNull Object[] list, int limit, int start, int length) {
int shift = start - limit;
for (int i = 0; i < shift; i++) {
if (!list[limit + i].equals(list[start + length - shift + i])) return 0;
@@ -195,20 +195,22 @@ public class Util {
return -shift;
}
- public static DiffFragment unite(DiffFragment fragment1, DiffFragment fragment2) {
+ @NotNull
+ public static DiffFragment unite(@NotNull DiffFragment fragment1, @NotNull DiffFragment fragment2) {
LOG.assertTrue(isSameType(fragment1, fragment2));
if (!fragment1.isOneSide()) {
- String unitedText1 = fragment1.getText1() + fragment2.getText1();
- String unitedText2 = fragment1.getText2() + fragment2.getText2();
+ DiffString unitedText1 = DiffString.concatenateNullable(fragment1.getText1(), fragment2.getText1());
+ DiffString unitedText2 = DiffString.concatenateNullable(fragment1.getText2(), fragment2.getText2());
LOG.assertTrue(fragment1.isEqual() == fragment2.isEqual());
return fragment1.isEqual() ? DiffFragment.unchanged(unitedText1, unitedText2) :
new DiffFragment(unitedText1, unitedText2);
}
FragmentSide side = FragmentSide.chooseSide(fragment1);
- return side.createFragment(side.getText(fragment1) + side.getText(fragment2), null, fragment1.isModified());
+ return side
+ .createFragment(DiffString.concatenateNullable(side.getText(fragment1), side.getText(fragment2)), null, fragment1.isModified());
}
- public static boolean isSameType(DiffFragment fragment1, DiffFragment fragment2) {
+ public static boolean isSameType(@NotNull DiffFragment fragment1, @NotNull DiffFragment fragment2) {
if (fragment1.isEqual()) return fragment2.isEqual();
if (fragment1.isChange()) return fragment2.isChange();
if (fragment1.getText1() == null) return fragment2.getText1() == null;
@@ -217,52 +219,46 @@ public class Util {
return false;
}
- public static String getText(DiffFragment[] fragments, FragmentSide side) {
- StringBuffer buffer = new StringBuffer();
+ @NotNull
+ public static DiffString getText(@NotNull DiffFragment[] fragments, @NotNull FragmentSide side) {
+ DiffString[] data = new DiffString[fragments.length];
for (int i = 0; i < fragments.length; i++) {
DiffFragment fragment = fragments[i];
- String text = side.getText(fragment);
- if (text != null) buffer.append(text);
+ data[i] = side.getText(fragment);
}
- return buffer.toString();
+ return DiffString.concatenate(data);
}
- public static DiffFragment concatenate(DiffFragment[] line) {
+ @NotNull
+ public static DiffFragment concatenate(@NotNull DiffFragment[] line) {
return concatenate(line, 0, line.length);
}
- public static DiffFragment concatenate(DiffFragment[] line, int from, int to) {
- String[] data1 = new String[to - from];
- String[] data2 = new String[to - from];
+ @NotNull
+ public static DiffFragment concatenate(@NotNull DiffFragment[] line, int from, int to) {
+ DiffString[] data1 = new DiffString[to - from];
+ DiffString[] data2 = new DiffString[to - from];
- int len1 = 0;
- int len2 = 0;
boolean isEqual = true;
for (int i = 0; i < to - from; i++) {
- isEqual &= line[i + from].isEqual();
- data1[i] = line[i + from].getText1();
- data2[i] = line[i + from].getText2();
- len1 += data1[i] == null ? 0 : data1[i].length();
- len2 += data2[i] == null ? 0 : data2[i].length();
- }
-
- StringBuilder buffer1 = new StringBuilder(len1);
- StringBuilder buffer2 = new StringBuilder(len2);
- for (int i = 0; i < to - from; i++) {
- if (data1[i] != null) buffer1.append(data1[i]);
- if (data2[i] != null) buffer2.append(data2[i]);
+ DiffFragment fragment = line[from + i];
+ isEqual &= fragment.isEqual();
+ data1[i] = fragment.getText1();
+ data2[i] = fragment.getText2();
}
- String text1 = notEmptyContent(buffer1);
- String text2 = notEmptyContent(buffer2);
+ DiffString text1 = notEmptyContent(DiffString.concatenate(data1));
+ DiffString text2 = notEmptyContent(DiffString.concatenate(data2));
return isEqual ? DiffFragment.unchanged(text1, text2) : new DiffFragment(text1, text2);
}
- private static String notEmptyContent(StringBuilder buffer) {
- return buffer.length() > 0 ? buffer.toString() : null;
+ @Nullable
+ private static DiffString notEmptyContent(@NotNull DiffString string) {
+ return string.length() > 0 ? string : null;
}
- public static DiffFragment[][] uniteFormattingOnly(DiffFragment[][] lines) {
+ @NotNull
+ public static DiffFragment[][] uniteFormattingOnly(@NotNull DiffFragment[][] lines) {
List2D result = new List2D();
for (int i = 0; i < lines.length; i++) {
DiffFragment[] line = lines[i];
@@ -276,20 +272,20 @@ public class Util {
return result.toArray();
}
- private static boolean areEqualOrFormatting(DiffFragment[] fragments) {
+ private static boolean areEqualOrFormatting(@NotNull DiffFragment[] fragments) {
for (int i = 0; i < fragments.length; i++) {
DiffFragment fragment = fragments[i];
if (fragment.isEqual()) continue;
for (int side = 0; side < 2; side++) {
- String text = FragmentSide.fromIndex(side).getText(fragment);
- if (text == null || text.trim().isEmpty()) continue;
+ DiffString text = FragmentSide.fromIndex(side).getText(fragment);
+ if (text == null || text.isEmptyOrSpaces()) continue;
return false;
}
}
return true;
}
- private static boolean areEqual(DiffFragment[] fragments) {
+ private static boolean areEqual(@NotNull DiffFragment[] fragments) {
for (int i = 0; i < fragments.length; i++) {
DiffFragment fragment = fragments[i];
if (!fragment.isEqual()) return false;
@@ -297,7 +293,8 @@ public class Util {
return true;
}
- public static DiffFragment[] cutFirst(DiffFragment[] fragments) {
+ @NotNull
+ public static DiffFragment[] cutFirst(@NotNull DiffFragment[] fragments) {
fragments = transformHeadInsert(fragments, FragmentSide.SIDE1);
fragments = transformHeadInsert(fragments, FragmentSide.SIDE2);
@@ -307,10 +304,10 @@ public class Util {
for (int i = 0; i < fragments.length; i++) {
DiffFragment fragment = fragments[i];
if (fragment == null) continue;
- String text = side.getText(fragment);
+ DiffString text = side.getText(fragment);
if (text == null || text.isEmpty()) continue;
text = text.length() > 1 ? text.substring(1) : null;
- String otherText = side.getOtherText(fragment);
+ DiffString otherText = side.getOtherText(fragment);
if (otherText == null && text == null) {
fragments[i] = null;
nullCount++;
@@ -330,7 +327,8 @@ public class Util {
return result;
}
- private static DiffFragment[] transformHeadInsert(DiffFragment[] fragments, FragmentSide side) {
+ @NotNull
+ private static DiffFragment[] transformHeadInsert(@NotNull DiffFragment[] fragments, @NotNull FragmentSide side) {
// transforms {abc}abcd into a{bca}bcd
if (fragments.length >= 2) {
DiffFragment first = fragments[0];
@@ -341,15 +339,15 @@ public class Util {
if (side.getText(first) != null) {
return fragments;
}
- String rightText = side.getOtherText(first);
- String secondText = side.getText(second);
+ DiffString rightText = side.getOtherText(first);
+ DiffString secondText = side.getText(second);
if (!Comparing.equal(side.getOtherText(second), secondText)) {
return fragments;
}
if (secondText.charAt(0) == rightText.charAt(0)) {
List<DiffFragment> result = new ArrayList<DiffFragment>();
result.add(side.createFragment(rightText.substring(0, 1), rightText.substring(0, 1), false));
- result.add(side.createFragment(null, rightText.substring(1) + secondText.substring(0, 1), true));
+ result.add(side.createFragment(null, DiffString.concatenate(rightText.substring(1), secondText.substring(0, 1)), true));
result.add(side.createFragment(secondText.substring(1), secondText.substring(1), second.isModified()));
result.addAll(Arrays.asList(fragments).subList(2, fragments.length));
return result.toArray(new DiffFragment[result.size()]);
@@ -363,11 +361,11 @@ public class Util {
super(line0, line1, deleted, inserted, null);
}
- public MyChange copyNext(Diff.Change change) {
+ public MyChange copyNext(@NotNull Diff.Change change) {
return copyNext(change, 0);
}
- public MyChange copyNext(Diff.Change change, int shift) {
+ public MyChange copyNext(@NotNull Diff.Change change, int shift) {
MyChange result = new MyChange(change.line0 + shift, change.line1 + shift, change.deleted, change.inserted);
setNext(result);
return result;
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/processing/ByWord.java b/platform/util/src/com/intellij/openapi/diff/impl/processing/ByWord.java
index 21740dc83a67..9aa43f5f1708 100644
--- a/platform/util/src/com/intellij/openapi/diff/impl/processing/ByWord.java
+++ b/platform/util/src/com/intellij/openapi/diff/impl/processing/ByWord.java
@@ -20,13 +20,16 @@ import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.ComparisonPolicy;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
import com.intellij.openapi.diff.impl.highlighting.Util;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.util.TextRange;
import com.intellij.util.diff.Diff;
import com.intellij.util.diff.FilesTooBigForDiffException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
import java.util.ArrayList;
-public class ByWord implements DiffPolicy{
+public class ByWord implements DiffPolicy {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.ByWord");
private final ComparisonPolicy myComparisonPolicy;
@@ -34,8 +37,15 @@ public class ByWord implements DiffPolicy{
myComparisonPolicy = comparisonPolicy;
}
+ @NotNull
+ @TestOnly
+ public DiffFragment[] buildFragments(@NotNull String text1, @NotNull String text2) throws FilesTooBigForDiffException {
+ return buildFragments(DiffString.create(text1), DiffString.create(text2));
+ }
+
+ @NotNull
@Override
- public DiffFragment[] buildFragments(String text1, String text2) throws FilesTooBigForDiffException {
+ public DiffFragment[] buildFragments(@NotNull DiffString text1, @NotNull DiffString text2) throws FilesTooBigForDiffException {
Word[] words1 = buildWords(text1, myComparisonPolicy);
Word[] words2 = buildWords(text2, myComparisonPolicy);
Diff.Change change = Diff.buildChanges(words1, words2);
@@ -54,8 +64,8 @@ public class ByWord implements DiffPolicy{
} else if (change.deleted == 0) {
processOneside(version2, change.inserted);
} else {
- String prefix1 = version1.getCurrentWordPrefix();
- String prefix2 = version2.getCurrentWordPrefix();
+ DiffString prefix1 = version1.getCurrentWordPrefix();
+ DiffString prefix2 = version2.getCurrentWordPrefix();
if (!prefix1.isEmpty() || !prefix2.isEmpty())
result.add(myComparisonPolicy.createFragment(prefix1, prefix2));
result.addChangedWords(change.deleted, change.inserted);
@@ -66,7 +76,7 @@ public class ByWord implements DiffPolicy{
result.addTails();
DiffFragment[] fragments = result.getFragments();
DiffFragment firstFragment = fragments[0];
- if (DiffFragment.isEmpty(firstFragment)) {
+ if (firstFragment.isEmpty()) {
DiffFragment[] newFragments = new DiffFragment[fragments.length - 1];
System.arraycopy(fragments, 1, newFragments, 0, newFragments.length);
fragments = newFragments;
@@ -74,7 +84,7 @@ public class ByWord implements DiffPolicy{
return fragments;
}
- private int countNotWhitespaces(Word[] words) {
+ private static int countNotWhitespaces(@NotNull Word[] words) {
int counter = 0;
for (int i = 0; i < words.length; i++) {
Word word = words[i];
@@ -83,7 +93,7 @@ public class ByWord implements DiffPolicy{
return counter;
}
- private int countEqual(Diff.Change change, Word[] words1, Word[] words2) {
+ private static int countEqual(Diff.Change change, @NotNull Word[] words1, @NotNull Word[] words2) {
int counter = 0;
int position1 = 0;
int position2 = 0;
@@ -111,19 +121,26 @@ public class ByWord implements DiffPolicy{
return counter;
}
- private void processOneside(FragmentBuilder.Version version, int wordCount) {
- String prefix = version.getCurrentWordPrefix();
+ private static void processOneside(@NotNull FragmentBuilder.Version version, int wordCount) {
+ DiffString prefix = version.getCurrentWordPrefix();
version.addOneSide(prefix, wordCount);
}
- private void processEquals(int changed1, int changed2, FragmentBuilder result) throws FilesTooBigForDiffException {
+ private static void processEquals(int changed1, int changed2, @NotNull FragmentBuilder result) throws FilesTooBigForDiffException {
while (result.getVersion1().getCurrentWordIndex() < changed1) {
result.processEqual();
}
LOG.assertTrue(changed2 == result.getVersion2().getCurrentWordIndex());
}
- static Word[] buildWords(String text, ComparisonPolicy policy) {
+ @NotNull
+ @TestOnly
+ static Word[] buildWords(@NotNull String text, @NotNull ComparisonPolicy policy) {
+ return buildWords(DiffString.create(text), policy);
+ }
+
+ @NotNull
+ static Word[] buildWords(@NotNull DiffString text, @NotNull ComparisonPolicy policy) {
ArrayList<Word> words = new ArrayList<Word>();
if (text.isEmpty() || !Character.isWhitespace(text.charAt(0)))
words.add(policy.createFormatting(text, TextRange.EMPTY_RANGE));
@@ -167,7 +184,7 @@ public class ByWord implements DiffPolicy{
private final DiffCorrection.ChangedSpace CORRECTION;
private final ComparisonPolicy myComparisonPolicy;
- public FragmentBuilder(Word[] words1, Word[] words2, ComparisonPolicy comparisonPolicy, String text1, String text2) {
+ public FragmentBuilder(@NotNull Word[] words1, @NotNull Word[] words2, @NotNull ComparisonPolicy comparisonPolicy, @NotNull DiffString text1, @NotNull DiffString text2) {
myVersion1 = new Version(words1, text1, this, true);
myVersion2 = new Version(words2, text2, this, false);
BY_CHAR = new ByChar(comparisonPolicy);
@@ -175,24 +192,27 @@ public class ByWord implements DiffPolicy{
myComparisonPolicy = comparisonPolicy;
}
+ @NotNull
public DiffFragment[] getFragments() {
return myFragments.toArray(new DiffFragment[myFragments.size()]);
}
+ @NotNull
public Version getVersion1() { return myVersion1; }
+ @NotNull
public Version getVersion2() { return myVersion2; }
- private void addAll(DiffFragment[] fragments) {
+ private void addAll(@NotNull DiffFragment[] fragments) {
for (int i = 0; i < fragments.length; i++) {
DiffFragment fragment = fragments[i];
add(fragment);
}
}
- private void add(DiffFragment fragment) {
- String text1 = fragment.getText1();
- String text2 = fragment.getText2();
+ private void add(@NotNull DiffFragment fragment) {
+ DiffString text1 = fragment.getText1();
+ DiffString text2 = fragment.getText2();
if (text1 != null) myVersion1.addOffset(text1.length());
if (text2 != null) myVersion2.addOffset(text2.length());
if (fragment.isEqual() && !myFragments.isEmpty()) {
@@ -207,7 +227,7 @@ public class ByWord implements DiffPolicy{
myFragments.add(fragment);
}
- private void addEqual(Word word1, Word word2) throws FilesTooBigForDiffException {
+ private void addEqual(@NotNull Word word1, @NotNull Word word2) throws FilesTooBigForDiffException {
addAll(CORRECTION.correct(new DiffFragment[]{myComparisonPolicy.createFragment(word1, word2)}));
}
@@ -221,19 +241,20 @@ public class ByWord implements DiffPolicy{
myVersion2.incCurrentWord();
}
- private DiffFragment[] fragmentsByChar(String text1, String text2) throws FilesTooBigForDiffException {
+ @NotNull
+ private DiffFragment[] fragmentsByChar(@NotNull DiffString text1, @NotNull DiffString text2) throws FilesTooBigForDiffException {
if (text1.isEmpty() && text2.isEmpty()) {
return DiffFragment.EMPTY_ARRAY;
}
- final String side1 = myVersion1.getPrevChar() + text1;
- final String side2 = myVersion2.getPrevChar() + text2;
+ final DiffString side1 = text1.preappend(myVersion1.getPrevChar());
+ final DiffString side2 = text2.preappend(myVersion2.getPrevChar());
DiffFragment[] fragments = BY_CHAR.buildFragments(side1, side2);
return Util.cutFirst(fragments);
}
private void addPostfixes() throws FilesTooBigForDiffException {
- String postfix1 = myVersion1.getCurrentWordPostfixAndOneMore();
- String postfix2 = myVersion2.getCurrentWordPostfixAndOneMore();
+ DiffString postfix1 = myVersion1.getCurrentWordPostfixAndOneMore();
+ DiffString postfix2 = myVersion2.getCurrentWordPostfixAndOneMore();
int length1 = postfix1.length();
int length2 = postfix2.length();
DiffFragment wholePostfix = myComparisonPolicy.createFragment(postfix1, postfix2);
@@ -245,20 +266,23 @@ public class ByWord implements DiffPolicy{
DiffFragment[] fragments = BY_CHAR.buildFragments(postfix1, postfix2);
DiffFragment firstFragment = fragments[0];
if (firstFragment.isEqual()) {
- final String text1 = cutLast(firstFragment.getText1(), length1);
- final String text2 = cutLast(firstFragment.getText2(), length2);
+ final DiffString text1 = cutLast(firstFragment.getText1(), length1);
+ final DiffString text2 = cutLast(firstFragment.getText2(), length2);
add(myComparisonPolicy.createFragment(text1, text2));
//add(firstFragment);
}
}
}
- private String cutLast(String text, int length) {
+ @NotNull
+ private static DiffString cutLast(@NotNull DiffString text, int length) {
if (text.length() < length) return text;
- else return text.substring(0, text.length() - 1);
+ else {
+ return text.substring(0, text.length() - 1);
+ }
}
- private void addOneSide(String text, FragmentSide side) {
+ private void addOneSide(@NotNull DiffString text, @NotNull FragmentSide side) {
DiffFragment fragment = side.createFragment(text, null, false);
add(myComparisonPolicy.createFragment(fragment.getText1(), fragment.getText2()));
}
@@ -270,8 +294,8 @@ public class ByWord implements DiffPolicy{
}
public void addTails() throws FilesTooBigForDiffException {
- String tail1 = myVersion1.getNotProcessedTail();
- String tail2 = myVersion2.getNotProcessedTail();
+ DiffString tail1 = myVersion1.getNotProcessedTail();
+ DiffString tail2 = myVersion2.getNotProcessedTail();
if (tail1.isEmpty() && tail2.isEmpty()) return;
DiffFragment[] fragments = fragmentsByChar(tail1, tail2);
if (!myFragments.isEmpty()) {
@@ -301,14 +325,14 @@ public class ByWord implements DiffPolicy{
}
public static class Version {
- private final Word[] myWords;
+ @NotNull private final Word[] myWords;
private int myCurrentWord = 0;
private int myOffset = 0;
- private final String myText;
- private final FragmentBuilder myBuilder;
+ @NotNull private final DiffString myText;
+ @NotNull private final FragmentBuilder myBuilder;
private final FragmentSide mySide;
- public Version(Word[] words, String text, FragmentBuilder builder, boolean delete) {
+ public Version(@NotNull Word[] words, @NotNull DiffString text, @NotNull FragmentBuilder builder, boolean delete) {
myWords = words;
myText = text;
myBuilder = builder;
@@ -331,7 +355,8 @@ public class ByWord implements DiffPolicy{
incCurrentWord(1);
}
- public String getWordSequence(int wordCount) {
+ @NotNull
+ public DiffString getWordSequence(int wordCount) {
int start = myWords[myCurrentWord].getStart();
int end = myWords[myCurrentWord+wordCount-1].getEnd();
return myText.substring(start, end);
@@ -341,22 +366,26 @@ public class ByWord implements DiffPolicy{
myCurrentWord += inserted;
}
+ @NotNull
public Word getCurrentWord() {
return myWords[myCurrentWord];
}
- public String getCurrentWordPrefix() {
+ @NotNull
+ public DiffString getCurrentWordPrefix() {
return getCurrentWord().getPrefix(getProcessedOffset());
}
- public String getCurrentWordPostfixAndOneMore() {
+ @NotNull
+ public DiffString getCurrentWordPostfixAndOneMore() {
int nextStart = myCurrentWord < myWords.length - 1 ? myWords[myCurrentWord + 1].getStart() : myText.length();
Word word = getCurrentWord();
- String postfix = myText.substring(word.getEnd(), nextStart);
- return postfix + (nextStart == myText.length() ? '\n' : myText.charAt(nextStart));
+ DiffString postfix = myText.substring(word.getEnd(), nextStart);
+ return postfix.append(nextStart == myText.length() ? '\n' : myText.charAt(nextStart));
}
- public String getNotProcessedTail() {
+ @NotNull
+ public DiffString getNotProcessedTail() {
LOG.assertTrue(myCurrentWord == myWords.length);
return myText.substring(myOffset, myText.length());
}
@@ -365,7 +394,7 @@ public class ByWord implements DiffPolicy{
return myOffset == 0 ? '\n' : myText.charAt(myOffset - 1);
}
- public void addOneSide(String prefix, int wordCount) {
+ public void addOneSide(@NotNull DiffString prefix, int wordCount) {
if (!prefix.isEmpty()) myBuilder.addOneSide(prefix, mySide);
myBuilder.addOneSide(getWordSequence(wordCount), mySide);
incCurrentWord(wordCount);
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/processing/DiffCorrection.java b/platform/util/src/com/intellij/openapi/diff/impl/processing/DiffCorrection.java
index ee8db1c1447e..a97b1c502aa2 100644
--- a/platform/util/src/com/intellij/openapi/diff/impl/processing/DiffCorrection.java
+++ b/platform/util/src/com/intellij/openapi/diff/impl/processing/DiffCorrection.java
@@ -16,7 +16,7 @@
package com.intellij.openapi.diff.impl.processing;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.diff.LineTokenizer;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.ComparisonPolicy;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
@@ -48,14 +48,18 @@ public interface DiffCorrection {
}
@Override
- public void process(DiffFragment fragment, FragmentsCollector collector) throws FilesTooBigForDiffException {
+ public void process(@NotNull DiffFragment fragment, @NotNull FragmentsCollector collector) throws FilesTooBigForDiffException {
+ DiffString text1 = fragment.getText1();
+ DiffString text2 = fragment.getText2();
if (!fragment.isEqual()) {
if (myComparisonPolicy.isEqual(fragment))
- fragment = myComparisonPolicy.createFragment(fragment.getText1(), fragment.getText2());
+ fragment = myComparisonPolicy.createFragment(text1, text2);
collector.add(fragment);
} else {
- String[] lines1 = new LineTokenizer(fragment.getText1()).execute();
- String[] lines2 = new LineTokenizer(fragment.getText2()).execute();
+ assert text1 != null;
+ assert text2 != null;
+ DiffString[] lines1 = text1.tokenize();
+ DiffString[] lines2 = text2.tokenize();
LOG.assertTrue(lines1.length == lines2.length);
for (int i = 0; i < lines1.length; i++)
collector.addAll(myDiffPolicy.buildFragments(lines1[i], lines2[i]));
@@ -77,45 +81,39 @@ public interface DiffCorrection {
}
@Override
- public void process(DiffFragment fragment, FragmentsCollector collector) throws FilesTooBigForDiffException {
+ public void process(@NotNull DiffFragment fragment, @NotNull FragmentsCollector collector) throws FilesTooBigForDiffException {
if (!fragment.isChange()) {
collector.add(fragment);
return;
}
- String text1 = fragment.getText1();
- String text2 = fragment.getText2();
+ DiffString text1 = fragment.getText1();
+ DiffString text2 = fragment.getText2();
while (StringUtil.startsWithChar(text1, '\n') || StringUtil.startsWithChar(text2, '\n')) {
- String newLine1 = null;
- String newLine2 = null;
+ DiffString newLine1 = null;
+ DiffString newLine2 = null;
if (StringUtil.startsWithChar(text1, '\n')) {
- newLine1 = "\n";
+ newLine1 = DiffString.create("\n");
text1 = text1.substring(1);
}
if (StringUtil.startsWithChar(text2, '\n')) {
- newLine2 = "\n";
+ newLine2 = DiffString.create("\n");
text2 = text2.substring(1);
}
collector.add(new DiffFragment(newLine1, newLine2));
}
- String spaces1 = leadingSpaces(text1);
- String spaces2 = leadingSpaces(text2);
+ DiffString spaces1 = text1.getLeadingSpaces();
+ DiffString spaces2 = text2.getLeadingSpaces();
if (spaces1.isEmpty() && spaces2.isEmpty()) {
DiffFragment trailing = myComparisonPolicy.createFragment(text1, text2);
collector.add(trailing);
return;
}
collector.addAll(myDiffPolicy.buildFragments(spaces1, spaces2));
- DiffFragment textFragment = myComparisonPolicy.createFragment(text1.substring(spaces1.length(), text1.length()),
- text2.substring(spaces2.length(), text2.length()));
+ DiffFragment textFragment = myComparisonPolicy
+ .createFragment(text1.substring(spaces1.length(), text1.length()), text2.substring(spaces2.length(), text2.length()));
collector.add(textFragment);
}
- private String leadingSpaces(String text) {
- int i = 0;
- while (i < text.length() && text.charAt(i) == ' ') i++;
- return text.substring(0, i);
- }
-
@Override
public DiffFragment[] correct(DiffFragment[] fragments) throws FilesTooBigForDiffException {
FragmentsCollector collector = new FragmentsCollector();
@@ -125,7 +123,7 @@ public interface DiffCorrection {
}
interface FragmentProcessor<Collector> {
- void process(DiffFragment fragment, Collector collector) throws FilesTooBigForDiffException;
+ void process(@NotNull DiffFragment fragment, @NotNull Collector collector) throws FilesTooBigForDiffException;
}
class BaseFragmentRunner<ActualRunner extends BaseFragmentRunner> {
@@ -158,8 +156,7 @@ public interface DiffCorrection {
}
}
- // todo think where
- public static int getTextLength(String text) {
+ public static int getTextLength(DiffString text) {
return text != null ? text.length() : 0;
}
@@ -224,7 +221,7 @@ public interface DiffCorrection {
}
@Override
- public void process(DiffFragment fragment, FragmentBuffer buffer) {
+ public void process(@NotNull DiffFragment fragment, @NotNull FragmentBuffer buffer) {
if (fragment.isOneSide()) buffer.markIfNone(DEFAULT_MODE);
else buffer.add(fragment);
}
@@ -243,7 +240,7 @@ public interface DiffCorrection {
}
@Override
- public void process(DiffFragment fragment, FragmentBuffer buffer) {
+ public void process(@NotNull DiffFragment fragment, @NotNull FragmentBuffer buffer) {
if (fragment.isEqual()) buffer.markIfNone(EQUAL_MODE);
else if (ComparisonPolicy.TRIM_SPACE.isEqual(fragment)) buffer.markIfNone(FORMATTING_MODE);
else buffer.add(fragment);
@@ -273,10 +270,10 @@ public interface DiffCorrection {
}
@Override
- public void process(DiffFragment fragment, FragmentBuffer buffer) {
+ public void process(@NotNull DiffFragment fragment, @NotNull FragmentBuffer buffer) {
if (fragment.isEqual()) buffer.add(fragment);
else if (fragment.isOneSide()) {
- String text = FragmentSide.chooseSide(fragment).getText(fragment);
+ DiffString text = FragmentSide.chooseSide(fragment).getText(fragment);
if (StringUtil.endsWithChar(text, '\n'))
buffer.add(fragment);
else
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/processing/DiffPolicy.java b/platform/util/src/com/intellij/openapi/diff/impl/processing/DiffPolicy.java
index 21cfc3d1c679..4547252456f7 100644
--- a/platform/util/src/com/intellij/openapi/diff/impl/processing/DiffPolicy.java
+++ b/platform/util/src/com/intellij/openapi/diff/impl/processing/DiffPolicy.java
@@ -15,13 +15,20 @@
*/
package com.intellij.openapi.diff.impl.processing;
-import com.intellij.openapi.diff.LineTokenizer;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.ComparisonPolicy;
import com.intellij.util.diff.FilesTooBigForDiffException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
public interface DiffPolicy {
- DiffFragment[] buildFragments(String text1, String text2) throws FilesTooBigForDiffException;
+ @NotNull
+ DiffFragment[] buildFragments(@NotNull DiffString text1, @NotNull DiffString text2) throws FilesTooBigForDiffException;
+
+ @NotNull
+ @TestOnly
+ DiffFragment[] buildFragments(@NotNull String text1, @NotNull String text2) throws FilesTooBigForDiffException;
DiffPolicy LINES_WO_FORMATTING = new LineBlocks(ComparisonPolicy.IGNORE_SPACE);
DiffPolicy DEFAULT_LINES = new LineBlocks(ComparisonPolicy.DEFAULT);
@@ -33,10 +40,17 @@ public interface DiffPolicy {
myComparisonPolicy = comparisonPolicy;
}
+ @NotNull
+ @TestOnly
+ public DiffFragment[] buildFragments(@NotNull String text1, @NotNull String text2) throws FilesTooBigForDiffException {
+ return buildFragments(DiffString.create(text1), DiffString.create(text2));
+ }
+
+ @NotNull
@Override
- public DiffFragment[] buildFragments(String text1, String text2) throws FilesTooBigForDiffException {
- String[] strings1 = new LineTokenizer(text1).execute();
- String[] strings2 = new LineTokenizer(text2).execute();
+ public DiffFragment[] buildFragments(@NotNull DiffString text1, @NotNull DiffString text2) throws FilesTooBigForDiffException {
+ DiffString[] strings1 = text1.tokenize();
+ DiffString[] strings2 = text2.tokenize();
return myComparisonPolicy.buildDiffFragmentsFromLines(strings1, strings2);
}
@@ -49,13 +63,20 @@ public interface DiffPolicy {
myComparisonPolicy = comparisonPolicy;
}
+ @NotNull
+ @TestOnly
+ public DiffFragment[] buildFragments(@NotNull String text1, @NotNull String text2) throws FilesTooBigForDiffException {
+ return buildFragments(DiffString.create(text1), DiffString.create(text2));
+ }
+
+ @NotNull
@Override
- public DiffFragment[] buildFragments(String text1, String text2) throws FilesTooBigForDiffException {
+ public DiffFragment[] buildFragments(@NotNull DiffString text1, @NotNull DiffString text2) throws FilesTooBigForDiffException {
return myComparisonPolicy.buildFragments(splitByChar(text1), splitByChar(text2));
}
- private String[] splitByChar(String text) {
- String[] result = new String[text.length()];
+ private static DiffString[] splitByChar(@NotNull DiffString text) {
+ DiffString[] result = new DiffString[text.length()];
for (int i = 0; i < result.length; i++) {
result[i] = text.substring(i, i + 1);
}
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/processing/Formatting.java b/platform/util/src/com/intellij/openapi/diff/impl/processing/Formatting.java
index 8a520f2ffcb5..a4eaf356b23d 100644
--- a/platform/util/src/com/intellij/openapi/diff/impl/processing/Formatting.java
+++ b/platform/util/src/com/intellij/openapi/diff/impl/processing/Formatting.java
@@ -15,10 +15,18 @@
*/
package com.intellij.openapi.diff.impl.processing;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
public class Formatting extends Word {
- public Formatting(String text, TextRange range) {
+ @TestOnly
+ public Formatting(@NotNull String baseText, @NotNull TextRange range) {
+ this(DiffString.create(baseText), range);
+ }
+
+ public Formatting(@NotNull DiffString text, @NotNull TextRange range) {
super(text, range);
}
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/processing/LineFragmentsCollector.java b/platform/util/src/com/intellij/openapi/diff/impl/processing/LineFragmentsCollector.java
index fd8a22d974bd..75342869c566 100644
--- a/platform/util/src/com/intellij/openapi/diff/impl/processing/LineFragmentsCollector.java
+++ b/platform/util/src/com/intellij/openapi/diff/impl/processing/LineFragmentsCollector.java
@@ -15,11 +15,14 @@
*/
package com.intellij.openapi.diff.impl.processing;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.fragments.LineFragment;
import com.intellij.openapi.diff.impl.util.TextDiffTypeEnum;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -30,14 +33,14 @@ class LineFragmentsCollector {
private int myOffset1 = 0;
private int myOffset2 = 0;
- private LineFragment addFragment(TextDiffTypeEnum type, String text1, String text2) {
+ @NotNull
+ private LineFragment addFragment(@Nullable TextDiffTypeEnum type, @Nullable DiffString text1, @Nullable DiffString text2) {
int lines1 = countLines(text1);
int lines2 = countLines(text2);
int endOffset1 = myOffset1 + getLength(text1);
int endOffset2 = myOffset2 + getLength(text2);
- LineFragment lineFragment = new LineFragment(myLine1, lines1, myLine2, lines2, type,
- new TextRange(myOffset1, endOffset1),
- new TextRange(myOffset2, endOffset2));
+ LineFragment lineFragment =
+ new LineFragment(myLine1, lines1, myLine2, lines2, type, new TextRange(myOffset1, endOffset1), new TextRange(myOffset2, endOffset2));
myLine1 += lines1;
myLine2 += lines2;
myOffset1 = endOffset1;
@@ -46,18 +49,19 @@ class LineFragmentsCollector {
return lineFragment;
}
- public LineFragment addDiffFragment(DiffFragment fragment) {
+ @NotNull
+ public LineFragment addDiffFragment(@NotNull DiffFragment fragment) {
return addFragment(getType(fragment), fragment.getText1(), fragment.getText2());
}
- static int getLength(String text) {
+ static int getLength(@Nullable DiffString text) {
return text == null ? 0 : text.length();
}
- private static int countLines(String text) {
+ private static int countLines(@Nullable DiffString text) {
if (text == null || text.isEmpty()) return 0;
int count = StringUtil.countNewLines(text);
- if (text.charAt(text.length()-1) != '\n') count++;
+ if (text.charAt(text.length() - 1) != '\n') count++;
return count;
}
@@ -65,7 +69,8 @@ class LineFragmentsCollector {
return myLineFragments;
}
- static TextDiffTypeEnum getType(DiffFragment fragment) {
+ @Nullable
+ static TextDiffTypeEnum getType(@NotNull DiffFragment fragment) {
TextDiffTypeEnum type;
if (fragment.getText1() == null) type = TextDiffTypeEnum.INSERT;
else if (fragment.getText2() == null) type = TextDiffTypeEnum.DELETED;
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/processing/UniteSameType.java b/platform/util/src/com/intellij/openapi/diff/impl/processing/UniteSameType.java
index ee166ceabb1e..bf21f1066ad2 100644
--- a/platform/util/src/com/intellij/openapi/diff/impl/processing/UniteSameType.java
+++ b/platform/util/src/com/intellij/openapi/diff/impl/processing/UniteSameType.java
@@ -16,10 +16,12 @@
package com.intellij.openapi.diff.impl.processing;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
import com.intellij.openapi.diff.impl.highlighting.Util;
import com.intellij.util.diff.FilesTooBigForDiffException;
+import org.jetbrains.annotations.NotNull;
class UniteSameType implements DiffCorrection {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.UniteSameType");
@@ -29,7 +31,8 @@ class UniteSameType implements DiffCorrection {
return unitSameTypes(covertSequentialOneSideToChange(unitSameTypes(fragments)));
}
- private DiffFragment[] unitSameTypes(DiffFragment[] fragments) {
+ @NotNull
+ private static DiffFragment[] unitSameTypes(@NotNull DiffFragment[] fragments) {
if (fragments.length < 2) return fragments;
DiffCorrection.FragmentsCollector collector = new DiffCorrection.FragmentsCollector();
DiffFragment previous = fragments[0];
@@ -47,7 +50,8 @@ class UniteSameType implements DiffCorrection {
return collector.toArray();
}
- private DiffFragment[] covertSequentialOneSideToChange(DiffFragment[] fragments) {
+ @NotNull
+ private static DiffFragment[] covertSequentialOneSideToChange(@NotNull DiffFragment[] fragments) {
if (fragments.length < 2) return fragments;
DiffCorrection.FragmentsCollector collector = new DiffCorrection.FragmentsCollector();
// DiffFragment previous = fragments[0];
@@ -58,9 +62,10 @@ class UniteSameType implements DiffCorrection {
if (previous == null) previous = fragment;
else {
FragmentSide side = FragmentSide.chooseSide(fragment);
- String previousText = side.getText(previous);
- if (previousText == null) previousText = "";
- previous = side.createFragment(previousText + side.getText(fragment), side.getOtherText(previous), true);
+ DiffString previousText = side.getText(previous);
+ if (previousText == null) previousText = DiffString.EMPTY;
+ previous = side.createFragment(DiffString.concatenateNullable(previousText, side.getText(fragment)),
+ side.getOtherText(previous), true);
}
} else {
if (previous != null) collector.add(previous);
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/processing/Word.java b/platform/util/src/com/intellij/openapi/diff/impl/processing/Word.java
index 3279fc4c1529..d9d67dc3e6f6 100644
--- a/platform/util/src/com/intellij/openapi/diff/impl/processing/Word.java
+++ b/platform/util/src/com/intellij/openapi/diff/impl/processing/Word.java
@@ -16,22 +16,32 @@
package com.intellij.openapi.diff.impl.processing;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
public class Word {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.Word");
- private final String myText;
- private final TextRange myRange;
+ @NotNull private final DiffString myBaseText;
+ @NotNull private final TextRange myRange;
+ @NotNull private final DiffString myText;
- public Word(String text, TextRange range) {
- myText = text;
+ @TestOnly
+ public Word(@NotNull String baseText, @NotNull TextRange range) {
+ this(DiffString.create(baseText), range);
+ }
+
+ public Word(@NotNull DiffString baseText, @NotNull TextRange range) {
+ myBaseText = baseText;
myRange = range;
+ myText = myBaseText.substring(myRange.getStartOffset(), myRange.getEndOffset());
LOG.assertTrue(myRange.getStartOffset() >= 0);
LOG.assertTrue(myRange.getEndOffset() >= myRange.getStartOffset(), myRange);
}
public int hashCode() {
- return getText().hashCode();
+ return myText.hashCode();
}
public boolean equals(Object obj) {
@@ -40,15 +50,17 @@ public class Word {
return getText().equals(other.getText());
}
- public String getText() {
- return myRange.substring(myText);
+ @NotNull
+ public DiffString getText() {
+ return myText;
}
- public String getPrefix(int fromPosition) {
- LOG.assertTrue(fromPosition >= 0, "" + fromPosition);
+ @NotNull
+ public DiffString getPrefix(int fromPosition) {
+ LOG.assertTrue(fromPosition >= 0, fromPosition);
int wordStart = myRange.getStartOffset();
- LOG.assertTrue(fromPosition <= wordStart, "" + fromPosition + " " + wordStart);
- return myText.substring(fromPosition, wordStart);
+ LOG.assertTrue(fromPosition <= wordStart, fromPosition + " " + wordStart);
+ return myBaseText.substring(fromPosition, wordStart);
}
public int getEnd() {
@@ -60,7 +72,7 @@ public class Word {
}
public String toString() {
- return getText();
+ return myText.toString();
}
public boolean isWhitespace() {
@@ -70,10 +82,10 @@ public class Word {
public boolean atEndOfLine() {
int start = myRange.getStartOffset();
if (start == 0) return true;
- if (myText.charAt(start - 1) == '\n') return true;
+ if (myBaseText.charAt(start - 1) == '\n') return true;
int end = myRange.getEndOffset();
- if (end == myText.length()) return true;
- if (myText.charAt(end) == '\n') return true;
+ if (end == myBaseText.length()) return true;
+ if (myBaseText.charAt(end) == '\n') return true;
return false;
}
}
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/string/DiffString.java b/platform/util/src/com/intellij/openapi/diff/impl/string/DiffString.java
new file mode 100644
index 000000000000..76aa43418ccc
--- /dev/null
+++ b/platform/util/src/com/intellij/openapi/diff/impl/string/DiffString.java
@@ -0,0 +1,420 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.diff.impl.string;
+
+import com.intellij.openapi.diff.LineTokenizerBase;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class DiffString implements CharSequence {
+ @NotNull public static final DiffString EMPTY = new DiffString(new char[0], 0, 0);
+
+ @NotNull private final char[] myData;
+ private final int myStart;
+ private final int myLength;
+ private int myHash;
+
+ @Nullable
+ public static DiffString createNullable(@Nullable String string) {
+ if (string == null) return null;
+ return create(string);
+ }
+
+ @NotNull
+ public static DiffString create(@NotNull String string) {
+ if (string.isEmpty()) return EMPTY;
+ return create(string.toCharArray());
+ }
+
+ @NotNull
+ static DiffString create(@NotNull char[] data) {
+ return create(data, 0, data.length);
+ }
+
+ @NotNull
+ static DiffString create(@NotNull char[] data, int start, int length) {
+ if (length == 0) return EMPTY;
+ checkBounds(start, length, data.length);
+ return new DiffString(data, start, length);
+ }
+
+ private DiffString(@NotNull char[] data, int start, int length) {
+ myData = data;
+ myStart = start;
+ myLength = length;
+ }
+
+ @Override
+ public int length() {
+ return myLength;
+ }
+
+ public boolean isEmpty() {
+ return myLength == 0;
+ }
+
+ @Override
+ public char charAt(int index) {
+ if (index < 0 || index >= myLength) {
+ throw new StringIndexOutOfBoundsException(index);
+ }
+ return data(index);
+ }
+
+ public char data(int index) {
+ return myData[myStart + index];
+ }
+
+ @NotNull
+ public DiffString substring(int start) {
+ return substring(start, myLength);
+ }
+
+ @NotNull
+ public DiffString substring(int start, int end) {
+ if (start == 0 && end == myLength) return this;
+ checkBounds(start, end - start, myLength);
+ return create(myData, myStart + start, end - start);
+ }
+
+ @Override
+ public DiffString subSequence(int start, int end) {
+ return substring(start, end);
+ }
+
+ @NotNull
+ @Override
+ public String toString() {
+ return new String(myData, myStart, myLength);
+ }
+
+ @NotNull
+ public DiffString copy() {
+ return create(Arrays.copyOfRange(myData, myStart, myStart + myLength));
+ }
+
+ public void copyData(@NotNull char[] dst, int start) {
+ checkBounds(start, myLength, dst.length);
+ System.arraycopy(myData, myStart, dst, start, myLength);
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ DiffString that = (DiffString)o;
+
+ if (myLength != that.myLength) return false;
+ if (hashCode() != that.hashCode()) return false;
+ for (int i = 0; i < myLength; i++) {
+ if (data(i) != that.data(i)) return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int h = myHash;
+ if (h == 0) {
+ h = StringUtil.stringHashCode(myData, myStart, myStart + myLength);
+ if (h == 0) h = 1;
+ myHash = h;
+ }
+ return h;
+ }
+
+ @Nullable
+ public static DiffString concatenateNullable(@Nullable DiffString s1, @Nullable DiffString s2) {
+ if (s1 == null || s2 == null) {
+ if (s1 != null) return s1;
+ if (s2 != null) return s2;
+ return null;
+ }
+
+ return concatenate(s1, s2);
+ }
+
+ @NotNull
+ public static DiffString concatenate(@NotNull DiffString s1, @NotNull DiffString s2) {
+ if (s1.isEmpty()) return s2;
+ if (s2.isEmpty()) return s1;
+
+ if (s1.myData == s2.myData && s1.myStart + s1.myLength == s2.myStart) {
+ return create(s1.myData, s1.myStart, s1.myLength + s2.myLength);
+ }
+
+ char[] data = new char[s1.myLength + s2.myLength];
+ System.arraycopy(s1.myData, s1.myStart, data, 0, s1.myLength);
+ System.arraycopy(s2.myData, s2.myStart, data, s1.myLength, s2.myLength);
+ return create(data);
+ }
+
+ public static boolean canInplaceConcatenate(@NotNull DiffString s1, @NotNull DiffString s2) {
+ if (s1.isEmpty()) return true;
+ if (s2.isEmpty()) return true;
+
+ if (s1.myData == s2.myData && s1.myStart + s1.myLength == s2.myStart) {
+ return true;
+ }
+
+ return false;
+ }
+
+ @NotNull
+ public static DiffString concatenateCopying(@NotNull DiffString[] strings) {
+ return concatenateCopying(strings, 0, strings.length);
+ }
+
+ @NotNull
+ public static DiffString concatenateCopying(@NotNull DiffString[] strings, int start, int length) {
+ checkBounds(start, length, strings.length);
+
+ int len = 0;
+ for (int i = 0; i < length; i++) {
+ DiffString string = strings[start + i];
+ len += string == null ? 0 : string.myLength;
+ }
+
+ if (len == 0) return EMPTY;
+
+ char[] data = new char[len];
+ int index = 0;
+ for (int i = 0; i < length; i++) {
+ DiffString string = strings[start + i];
+ if (string == null || string.isEmpty()) continue;
+ System.arraycopy(string.myData, string.myStart, data, index, string.myLength);
+ index += string.myLength;
+ }
+ return create(data);
+ }
+
+ @NotNull
+ public static DiffString concatenate(@NotNull DiffString s, char c) {
+ if (s.myStart + s.myLength < s.myData.length && s.data(s.myLength) == c) {
+ return create(s.myData, s.myStart, s.myLength + 1);
+ }
+
+ char[] data = new char[s.myLength + 1];
+ System.arraycopy(s.myData, s.myStart, data, 0, s.myLength);
+ data[s.myLength] = c;
+ return create(data);
+ }
+
+ @NotNull
+ public static DiffString concatenate(char c, @NotNull DiffString s) {
+ if (s.myStart > 0 && s.data(-1) == c) {
+ return create(s.myData, s.myStart - 1, s.myLength + 1);
+ }
+
+ char[] data = new char[s.myLength + 1];
+ System.arraycopy(s.myData, s.myStart, data, 1, s.myLength);
+ data[0] = c;
+ return create(data);
+ }
+
+ @NotNull
+ public static DiffString concatenate(@NotNull DiffString[] strings) {
+ return concatenate(strings, 0, strings.length);
+ }
+
+ @NotNull
+ public static DiffString concatenate(@NotNull DiffString[] strings, int start, int length) {
+ checkBounds(start, length, strings.length);
+
+ char[] data = null;
+ int startIndex = 0;
+ int endIndex = 0;
+
+ boolean linearized = true;
+ for (int i = 0; i < length; i++) {
+ DiffString string = strings[start + i];
+ if (string == null || string.isEmpty()) continue;
+ if (data == null) {
+ data = string.myData;
+ startIndex = string.myStart;
+ endIndex = string.myStart + string.myLength;
+ continue;
+ }
+ if (data != string.myData || string.myStart != endIndex) {
+ linearized = false;
+ break;
+ }
+ endIndex += string.myLength;
+ }
+
+ if (linearized) {
+ if (data == null) return EMPTY;
+ return create(data, startIndex, endIndex - startIndex);
+ }
+
+ return concatenateCopying(strings, start, length);
+ }
+
+ @NotNull
+ public DiffString append(char c) {
+ return concatenate(this, c);
+ }
+
+ @NotNull
+ public DiffString preappend(char c) {
+ return concatenate(c, this);
+ }
+
+ public static boolean isWhiteSpace(char c) {
+ return StringUtil.isWhiteSpace(c);
+ }
+
+ public boolean isEmptyOrSpaces() {
+ if (isEmpty()) return true;
+
+ for (int i = 0; i < myLength; i++) {
+ if (!isWhiteSpace(data(i))) return false;
+ }
+ return true;
+ }
+
+ @NotNull
+ public DiffString trim() {
+ int start = 0;
+ int end = myLength;
+
+ while (start < end && isWhiteSpace(data(start))) start++;
+ while (end > start && isWhiteSpace(data(end - 1))) end--;
+
+ return substring(start, end);
+ }
+
+ @NotNull
+ public DiffString trimLeading() {
+ int i = 0;
+
+ while (i < myLength && isWhiteSpace(data(i))) i++;
+
+ return substring(i, myLength);
+ }
+
+ @NotNull
+ public DiffString trimTrailing() {
+ int end = myLength;
+
+ while (end > 0 && isWhiteSpace(data(end - 1))) end--;
+
+ return substring(0, end);
+ }
+
+ @NotNull
+ public DiffString getLeadingSpaces() {
+ int i = 0;
+
+ while (i < myLength && data(i) == ' ') i++;
+
+ return substring(0, i);
+ }
+
+ @NotNull
+ public DiffString skipSpaces() {
+ DiffString s = trim();
+ int count = 0;
+ for (int i = 0; i < s.myLength; i++) {
+ if (isWhiteSpace(s.data(i))) count++;
+ }
+ if (count == 0) return s;
+
+ char[] data = new char[s.myLength - count];
+ int index = 0;
+ for (int i = 0; i < s.myLength; i++) {
+ if (isWhiteSpace(s.data(i))) continue;
+ data[index] = s.data(i);
+ index++;
+ }
+ return create(data);
+ }
+
+ public int indexOf(char c) {
+ return StringUtil.indexOf(this, c);
+ }
+
+ public boolean endsWith(char c) {
+ if (isEmpty()) return false;
+ return data(myLength - 1) == c;
+ }
+
+ public static void checkBounds(int start, int length, int maxLength) {
+ if (start < 0) {
+ throw new StringIndexOutOfBoundsException(start);
+ }
+ if (length < 0) {
+ throw new StringIndexOutOfBoundsException(length);
+ }
+ if (start + length > maxLength) {
+ throw new StringIndexOutOfBoundsException(start + length);
+ }
+ }
+
+ @NotNull
+ public DiffString[] tokenize() {
+ return new LineTokenizer(this).execute();
+ }
+
+ public static class LineTokenizer extends LineTokenizerBase<DiffString> {
+ @NotNull private final DiffString myText;
+
+ public LineTokenizer(@NotNull DiffString text) {
+ myText = text;
+ }
+
+ @NotNull
+ public DiffString[] execute() {
+ ArrayList<DiffString> lines = new ArrayList<DiffString>();
+ doExecute(lines);
+ return ContainerUtil.toArray(lines, new DiffString[lines.size()]);
+ }
+
+ @Override
+ protected void addLine(List<DiffString> lines, int start, int end, boolean appendNewLine) {
+ if (appendNewLine) {
+ lines.add(myText.substring(start, end).append('\n'));
+ }
+ else {
+ lines.add(myText.substring(start, end));
+ }
+ }
+
+ @Override
+ protected char charAt(int index) {
+ return myText.data(index);
+ }
+
+ @Override
+ protected int length() {
+ return myText.length();
+ }
+
+ @NotNull
+ @Override
+ protected String substring(int start, int end) {
+ return myText.substring(start, end).toString();
+ }
+ }
+}
diff --git a/platform/util/src/com/intellij/openapi/diff/impl/string/DiffStringBuilder.java b/platform/util/src/com/intellij/openapi/diff/impl/string/DiffStringBuilder.java
new file mode 100644
index 000000000000..f1a700f22e15
--- /dev/null
+++ b/platform/util/src/com/intellij/openapi/diff/impl/string/DiffStringBuilder.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.diff.impl.string;
+
+import com.intellij.openapi.diff.impl.string.DiffString;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+
+public class DiffStringBuilder implements CharSequence {
+ @NotNull private char[] myData;
+ private int myLength;
+
+ public DiffStringBuilder() {
+ this(16);
+ }
+
+ public DiffStringBuilder(int len) {
+ myData = new char[len];
+ myLength = 0;
+ }
+
+ @Override
+ public int length() {
+ return myLength;
+ }
+
+ @Override
+ public char charAt(int index) {
+ if (index < 0 || index >= myLength) {
+ throw new StringIndexOutOfBoundsException(index);
+ }
+ return myData[index];
+ }
+
+ @Override
+ @NotNull
+ public CharSequence subSequence(int start, int end) {
+ DiffString.checkBounds(start, end, myLength);
+ return DiffString.create(myData, start, end - start);
+ }
+
+ @NotNull
+ public DiffString toDiffString() {
+ return DiffString.create(myData, 0, myLength);
+ }
+
+ @Override
+ @NotNull
+ public String toString() {
+ return toDiffString().toString();
+ }
+
+ private void ensureCapacityInternal(int neededCapacity) {
+ if (neededCapacity > myData.length) {
+ int newCapacity = myData.length;
+ while (newCapacity < neededCapacity) newCapacity *= 2;
+
+ myData = Arrays.copyOf(myData, newCapacity);
+ }
+ }
+
+ public void append(@NotNull DiffString s) {
+ if (s.isEmpty()) return;
+ ensureCapacityInternal(myLength + s.length());
+ s.copyData(myData, myLength);
+ myLength += s.length();
+ }
+}
diff --git a/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java b/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java
index 72dc236f0935..909c44db199b 100644
--- a/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java
+++ b/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.util.text.StringUtil;
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.*;
@@ -104,4 +105,15 @@ public class JDOMExternalizer {
}
}
}
+
+ public static List<String> loadStringsList(Element element, String rootName, String attrName) {
+ final List<String> paths = new LinkedList<String>();
+ if (element != null) {
+ @NotNull final List list = element.getChildren(rootName);
+ for (Object o : list) {
+ paths.add(((Element)o).getAttribute(attrName).getValue());
+ }
+ }
+ return paths;
+ }
} \ No newline at end of file
diff --git a/platform/util/src/com/intellij/openapi/util/Key.java b/platform/util/src/com/intellij/openapi/util/Key.java
index 949cb3e1ba46..09ef12949ccf 100644
--- a/platform/util/src/com/intellij/openapi/util/Key.java
+++ b/platform/util/src/com/intellij/openapi/util/Key.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.
@@ -42,6 +42,7 @@ public class Key<T> {
allKeys.put(myIndex, this);
}
+ // made final because many classes depend on one-to-one key index <-> key instance relationship. See e.g. UserDataHolderBase
public final int hashCode() {
return myIndex;
}
diff --git a/platform/util/src/com/intellij/util/LocalTimeCounter.java b/platform/util/src/com/intellij/util/LocalTimeCounter.java
index 1cfbdb7e4df0..41b09b723197 100644
--- a/platform/util/src/com/intellij/util/LocalTimeCounter.java
+++ b/platform/util/src/com/intellij/util/LocalTimeCounter.java
@@ -18,12 +18,14 @@ package com.intellij.util;
import java.util.concurrent.atomic.AtomicLong;
public class LocalTimeCounter {
+ /**
+ * VirtualFile.modificationStamp is kept modulo this mask, and is compared with other stamps. Let's avoid accidental stamp inequalities
+ * by normalizing all of them.
+ */
+ public static final int TIME_MASK = 0x00ffffff;
private static final AtomicLong ourCurrentTime = new AtomicLong();
- private LocalTimeCounter() {
- }
-
public static long currentTime() {
- return ourCurrentTime.incrementAndGet();
+ return TIME_MASK & (int)ourCurrentTime.incrementAndGet();
}
} \ No newline at end of file
diff --git a/platform/util/src/com/intellij/util/diff/PatienceIntLCS.java b/platform/util/src/com/intellij/util/diff/PatienceIntLCS.java
index 5acb8272c8fb..f20353e48ccf 100644
--- a/platform/util/src/com/intellij/util/diff/PatienceIntLCS.java
+++ b/platform/util/src/com/intellij/util/diff/PatienceIntLCS.java
@@ -120,7 +120,7 @@ public class PatienceIntLCS {
}
private int matchForward(int offset1, int offset2) {
- final int size = Math.min(myCount1 - offset1, myCount2 - offset2);
+ final int size = Math.min(myCount1 + myStart1 - offset1, myCount2 + myStart2 - offset2);
int idx = 0;
for (int i = 0; i < size; i++) {
if (!(myFirst[offset1 + i] == mySecond[offset2 + i])) break;
diff --git a/platform/util/src/com/intellij/util/io/DataExternalizer.java b/platform/util/src/com/intellij/util/io/DataExternalizer.java
index 44454294e398..f252424466be 100644
--- a/platform/util/src/com/intellij/util/io/DataExternalizer.java
+++ b/platform/util/src/com/intellij/util/io/DataExternalizer.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,12 +15,14 @@
*/
package com.intellij.util.io;
+import org.jetbrains.annotations.NotNull;
+
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public interface DataExternalizer<T> {
- void save(DataOutput out, T value) throws IOException;
+ void save(@NotNull DataOutput out, T value) throws IOException;
- T read(DataInput in) throws IOException;
+ T read(@NotNull DataInput in) throws IOException;
}
diff --git a/platform/util/src/com/intellij/util/io/EnumeratorStringDescriptor.java b/platform/util/src/com/intellij/util/io/EnumeratorStringDescriptor.java
index 1621cf3bc22c..a662aae3f527 100644
--- a/platform/util/src/com/intellij/util/io/EnumeratorStringDescriptor.java
+++ b/platform/util/src/com/intellij/util/io/EnumeratorStringDescriptor.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,13 +37,13 @@ public class EnumeratorStringDescriptor implements KeyDescriptor<String> {
}
@Override
- public void save(final DataOutput storage, @NotNull final String value) throws IOException {
+ public void save(@NotNull final DataOutput storage, @NotNull final String value) throws IOException {
final byte[] buffer = IOUtil.allocReadWriteUTFBuffer();
IOUtil.writeUTFFast(buffer, storage, value);
}
@Override
- public String read(final DataInput storage) throws IOException {
+ public String read(@NotNull final DataInput storage) throws IOException {
final byte[] buffer = IOUtil.allocReadWriteUTFBuffer();
return IOUtil.readUTFFast(buffer, storage);
}
diff --git a/platform/util/src/com/intellij/util/io/ExternalIntegerKeyDescriptor.java b/platform/util/src/com/intellij/util/io/ExternalIntegerKeyDescriptor.java
index 009581e5a098..cb3e1466295a 100644
--- a/platform/util/src/com/intellij/util/io/ExternalIntegerKeyDescriptor.java
+++ b/platform/util/src/com/intellij/util/io/ExternalIntegerKeyDescriptor.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,8 @@
*/
package com.intellij.util.io;
+import org.jetbrains.annotations.NotNull;
+
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
@@ -35,12 +37,12 @@ public class ExternalIntegerKeyDescriptor implements KeyDescriptor<Integer> {
}
@Override
- public void save(final DataOutput out, final Integer value) throws IOException {
+ public void save(@NotNull final DataOutput out, final Integer value) throws IOException {
DataInputOutputUtil.writeINT(out, value.intValue());
}
@Override
- public Integer read(final DataInput in) throws IOException {
+ public Integer read(@NotNull final DataInput in) throws IOException {
return DataInputOutputUtil.readINT(in);
}
} \ No newline at end of file
diff --git a/platform/util/src/com/intellij/util/io/InlineKeyDescriptor.java b/platform/util/src/com/intellij/util/io/InlineKeyDescriptor.java
index 8cf030a5d975..d64df97e574b 100644
--- a/platform/util/src/com/intellij/util/io/InlineKeyDescriptor.java
+++ b/platform/util/src/com/intellij/util/io/InlineKeyDescriptor.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,8 @@
*/
package com.intellij.util.io;
+import org.jetbrains.annotations.NotNull;
+
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
@@ -41,14 +43,14 @@ public abstract class InlineKeyDescriptor<T> implements KeyDescriptor<T> {
}
@Override
- public final void save(DataOutput out, T value) throws IOException {
+ public final void save(@NotNull DataOutput out, T value) throws IOException {
int v = toInt(value);
if (myCompactFormat) DataInputOutputUtil.writeINT(out, v);
else out.writeInt(v);
}
@Override
- public final T read(DataInput in) throws IOException {
+ public final T read(@NotNull DataInput in) throws IOException {
int n;
if (myCompactFormat) n = DataInputOutputUtil.readINT(in);
else n = in.readInt();
diff --git a/platform/util/src/com/intellij/util/io/MappedFileInputStream.java b/platform/util/src/com/intellij/util/io/MappedFileInputStream.java
index c67c816e6578..10a57dcf4c5c 100644
--- a/platform/util/src/com/intellij/util/io/MappedFileInputStream.java
+++ b/platform/util/src/com/intellij/util/io/MappedFileInputStream.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,24 +25,24 @@ import java.io.IOException;
import java.io.InputStream;
public class MappedFileInputStream extends InputStream {
- private ResizeableMappedFile raf;
+ private final ResizeableMappedFile raf;
private int cur;
private long limit;
- public MappedFileInputStream(final ResizeableMappedFile raf, final long pos, final long limit) {
+ public MappedFileInputStream(@NotNull ResizeableMappedFile raf, final long pos, final long limit) {
this.raf = raf;
setup(pos, limit);
}
+ public MappedFileInputStream(@NotNull ResizeableMappedFile raf, final long pos) throws IOException {
+ this(raf, pos, raf.length());
+ }
+
public void setup(final long pos, final long limit) {
this.cur = (int)pos;
this.limit = limit;
}
- public MappedFileInputStream(final ResizeableMappedFile raf, final long pos) throws IOException {
- this(raf, pos, raf.length());
- }
-
@Override
public int available()
{
@@ -67,7 +67,7 @@ public class MappedFileInputStream extends InputStream {
}
@Override
- public int read( @NotNull byte[] b, int offset, int length ) throws IOException
+ public int read(@NotNull byte[] b, int offset, int length ) throws IOException
{
//only allow a read of the amount available.
if( length > available() )
diff --git a/platform/util/src/com/intellij/util/io/NullableDataExternalizer.java b/platform/util/src/com/intellij/util/io/NullableDataExternalizer.java
index 7f8bba853fb4..897fa7d2084b 100644
--- a/platform/util/src/com/intellij/util/io/NullableDataExternalizer.java
+++ b/platform/util/src/com/intellij/util/io/NullableDataExternalizer.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.util.io;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.DataOutput;
@@ -32,7 +33,7 @@ public class NullableDataExternalizer<T> implements DataExternalizer<T> {
}
@Override
- public void save(DataOutput out, T value) throws IOException {
+ public void save(@NotNull DataOutput out, T value) throws IOException {
if (value == null) {
out.writeBoolean(false);
} else {
@@ -43,7 +44,7 @@ public class NullableDataExternalizer<T> implements DataExternalizer<T> {
@Override
@Nullable
- public T read(DataInput in) throws IOException {
+ public T read(@NotNull DataInput in) throws IOException {
final boolean isDefined = in.readBoolean();
if (isDefined) {
return myNotNullExternalizer.read(in);
diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java
index 5cb7ad4bf206..6903c6bcca14 100644
--- a/platform/util/src/com/intellij/util/ui/UIUtil.java
+++ b/platform/util/src/com/intellij/util/ui/UIUtil.java
@@ -45,6 +45,7 @@ import javax.swing.text.DefaultEditorKit;
import javax.swing.text.JTextComponent;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
+import javax.swing.undo.UndoManager;
import java.awt.*;
import java.awt.event.*;
import java.awt.font.FontRenderContext;
@@ -1584,6 +1585,7 @@ public class UIUtil {
g.setComposite(X_RENDER_ACTIVE.getValue() ? AlphaComposite.SrcOver : AlphaComposite.Src);
}
+ /** @see #pump() */
@TestOnly
public static void dispatchAllInvocationEvents() {
assert SwingUtilities.isEventDispatchThread() : Thread.currentThread();
@@ -1603,6 +1605,7 @@ public class UIUtil {
}
}
+ /** @see #dispatchAllInvocationEvents() */
@TestOnly
public static void pump() {
assert !SwingUtilities.isEventDispatchThread();
@@ -2778,4 +2781,28 @@ public class UIUtil {
}
return false;
}
+
+ public static void addUndoRedoActions(JTextComponent textComponent) {
+ final UndoManager undoManager = new UndoManager();
+ textComponent.getDocument().addUndoableEditListener(undoManager);
+ textComponent.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, SystemInfo.isMac? InputEvent.META_MASK : InputEvent.CTRL_MASK), "undoKeystroke");
+ textComponent.getActionMap().put("undoKeystroke", new AbstractAction() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (undoManager.canUndo()) {
+ undoManager.undo();
+ }
+ }
+ });
+ textComponent.getInputMap().put(
+ KeyStroke.getKeyStroke(KeyEvent.VK_Z, (SystemInfo.isMac? InputEvent.META_MASK : InputEvent.CTRL_MASK) | InputEvent.SHIFT_MASK), "redoKeystroke");
+ textComponent.getActionMap().put("redoKeystroke", new AbstractAction() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (undoManager.canRedo()) {
+ undoManager.redo();
+ }
+ }
+ });
+ }
}
diff --git a/platform/util/src/com/intellij/util/xmlb/TextBinding.java b/platform/util/src/com/intellij/util/xmlb/TextBinding.java
index a195b3b6b134..57cc3ef79315 100644
--- a/platform/util/src/com/intellij/util/xmlb/TextBinding.java
+++ b/platform/util/src/com/intellij/util/xmlb/TextBinding.java
@@ -32,6 +32,7 @@ public class TextBinding implements Binding {
@Override
public Object serialize(Object o, Object context, SerializationFilter filter) {
final Object v = myAccessor.read(o);
+ if (v == null) return context;
final Object node = myBinding.serialize(v, context, filter);
return new Text(((Content)node).getValue());
diff --git a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java
index d70588834481..7a147e074468 100644
--- a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java
+++ b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java
@@ -1029,6 +1029,31 @@ public class XmlSerializerTest extends TestCase {
}
}
+ public static class ConversionFromTextToAttributeBean {
+ @Property(surroundWithTag = false)
+ public ConditionBean myConditionBean = new ConditionBean();
+ }
+ @Tag("condition")
+ public static class ConditionBean {
+ @Attribute("expression")
+ public String myNewCondition;
+ @Text
+ public String myOldCondition;
+ }
+
+ public void testConversionFromTextToAttribute() {
+ ConversionFromTextToAttributeBean bean = new ConversionFromTextToAttributeBean();
+ bean.myConditionBean.myOldCondition = "2+2";
+ doSerializerTest("<ConversionFromTextToAttributeBean>\n" +
+ " <condition>2+2</condition>\n" +
+ "</ConversionFromTextToAttributeBean>", bean);
+
+ bean = new ConversionFromTextToAttributeBean();
+ bean.myConditionBean.myNewCondition = "2+2";
+ doSerializerTest("<ConversionFromTextToAttributeBean>\n" +
+ " <condition expression=\"2+2\" />\n" +
+ "</ConversionFromTextToAttributeBean>", bean);
+ }
public void testDeserializeInto() throws Exception {
BeanWithPublicFields bean = new BeanWithPublicFields();
diff --git a/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java b/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java
index 75918b5b56ca..9a78602ac8de 100644
--- a/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java
+++ b/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java
@@ -354,23 +354,31 @@ public class PatchReader {
PatchHunk hunk = new PatchHunk(startLineBefore-1, startLineBefore+linesBefore-1, startLineAfter-1, startLineAfter+linesAfter-1);
PatchLine lastLine = null;
- int numLines = linesBefore + linesAfter;
+ int before = 0;
+ int after = 0;
while (iterator.hasNext()) {
String hunkCurLine = iterator.next();
- -- numLines;
if (lastLine != null && hunkCurLine.startsWith(NO_NEWLINE_SIGNATURE)) {
lastLine.setSuppressNewLine(true);
continue;
}
- if (hunkCurLine.startsWith("--- ") && numLines == 0) {
- iterator.previous();
- break;
- }
- lastLine = parsePatchLine(hunkCurLine, 1);
+ lastLine = parsePatchLine(hunkCurLine, 1, before < linesBefore || after < linesAfter);
if (lastLine == null) {
iterator.previous();
break;
}
+ switch (lastLine.getType()) {
+ case CONTEXT:
+ before++;
+ after++;
+ break;
+ case ADD:
+ after++;
+ break;
+ case REMOVE:
+ before++;
+ break;
+ }
hunk.addLine(lastLine);
}
return hunk;
@@ -389,11 +397,16 @@ public class PatchReader {
@Nullable
private static PatchLine parsePatchLine(final String line, final int prefixLength) {
+ return parsePatchLine(line, prefixLength, true);
+ }
+
+ @Nullable
+ private static PatchLine parsePatchLine(final String line, final int prefixLength, boolean expectMeaningfulLines) {
PatchLine.Type type;
- if (line.startsWith("+")) {
+ if (line.startsWith("+") && expectMeaningfulLines) {
type = PatchLine.Type.ADD;
}
- else if (line.startsWith("-")) {
+ else if (line.startsWith("-") && expectMeaningfulLines) {
type = PatchLine.Type.REMOVE;
}
else if (line.startsWith(" ") || line.length() == 0) {
diff --git a/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/TextPatchBuilder.java b/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/TextPatchBuilder.java
index 7dc87ca57dc2..cbf110a9fe9d 100644
--- a/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/TextPatchBuilder.java
+++ b/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/TextPatchBuilder.java
@@ -15,7 +15,7 @@
*/
package com.intellij.openapi.diff.impl.patch;
-import com.intellij.openapi.diff.LineTokenizer;
+import com.intellij.openapi.diff.impl.string.DiffString;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.ComparisonPolicy;
import com.intellij.openapi.diff.impl.fragments.LineFragment;
@@ -111,16 +111,16 @@ public class TextPatchBuilder {
continue;
}
- final String beforeContent = beforeRevision.getContentAsString();
+ final DiffString beforeContent = DiffString.createNullable(beforeRevision.getContentAsString());
if (beforeContent == null) {
throw new VcsException("Failed to fetch old content for changed file " + beforeRevision.getPath().getPath());
}
- final String afterContent = afterRevision.getContentAsString();
+ final DiffString afterContent = DiffString.createNullable(afterRevision.getContentAsString());
if (afterContent == null) {
throw new VcsException("Failed to fetch new content for changed file " + afterRevision.getPath().getPath());
}
- String[] beforeLines = tokenize(beforeContent);
- String[] afterLines = tokenize(afterContent);
+ DiffString[] beforeLines = tokenize(beforeContent);
+ DiffString[] afterLines = tokenize(afterContent);
DiffFragment[] woFormattingBlocks;
DiffFragment[] step1lineFragments;
@@ -164,10 +164,10 @@ public class TextPatchBuilder {
checkCanceled();
for(int i=contextStart1; i<fragment.getStartingLine1(); i++) {
- addLineToHunk(hunk, beforeLines [i], PatchLine.Type.CONTEXT);
+ addLineToHunk(hunk, beforeLines[i], PatchLine.Type.CONTEXT);
}
for(int i=fragment.getStartingLine1(); i<fragment.getStartingLine1()+fragment.getModifiedLines1(); i++) {
- addLineToHunk(hunk, beforeLines [i], PatchLine.Type.REMOVE);
+ addLineToHunk(hunk, beforeLines[i], PatchLine.Type.REMOVE);
}
for(int i=fragment.getStartingLine2(); i<fragment.getStartingLine2()+fragment.getModifiedLines2(); i++) {
addLineToHunk(hunk, afterLines[i], PatchLine.Type.ADD);
@@ -175,14 +175,14 @@ public class TextPatchBuilder {
contextStart1 = fragment.getStartingLine1()+fragment.getModifiedLines1();
}
for(int i=contextStart1; i<contextEnd1; i++) {
- addLineToHunk(hunk, beforeLines [i], PatchLine.Type.CONTEXT);
+ addLineToHunk(hunk, beforeLines[i], PatchLine.Type.CONTEXT);
}
}
}
checkPathEndLine(patch, c.getAfter());
} else if (! beforeRevision.getPath().equals(afterRevision.getPath())) {
- final TextFilePatch movedPatch = buildMovedFile(myBasePath, beforeRevision, afterRevision, beforeLines);
+ final TextFilePatch movedPatch = buildMovedFile(myBasePath, beforeRevision, afterRevision);
checkPathEndLine(movedPatch, c.getAfter());
result.add(movedPatch);
}
@@ -205,8 +205,9 @@ public class TextPatchBuilder {
}
}
- private static String[] tokenize(String text) {
- return text.length() == 0 ? new String[]{text} : new LineTokenizer(text).execute();
+ @NotNull
+ private static DiffString[] tokenize(@NotNull DiffString text) {
+ return text.length() == 0 ? new DiffString[]{text} : text.tokenize();
}
private FilePatch buildBinaryPatch(final String basePath,
@@ -221,20 +222,20 @@ public class TextPatchBuilder {
return patch;
}
- private static void addLineToHunk(final PatchHunk hunk, final String line, final PatchLine.Type type) {
+ private static void addLineToHunk(@NotNull final PatchHunk hunk, @NotNull final DiffString line, final PatchLine.Type type) {
final PatchLine patchLine;
- if (!line.endsWith("\n")) {
- patchLine = new PatchLine(type, line);
+ if (!line.endsWith('\n')) {
+ patchLine = new PatchLine(type, line.toString());
patchLine.setSuppressNewLine(true);
}
else {
- patchLine = new PatchLine(type, line.substring(0, line.length()-1));
+ patchLine = new PatchLine(type, line.substring(0, line.length() - 1).toString());
}
hunk.addLine(patchLine);
}
private TextFilePatch buildMovedFile(final String basePath, final AirContentRevision beforeRevision,
- final AirContentRevision afterRevision, final String[] lines) throws VcsException {
+ final AirContentRevision afterRevision) throws VcsException {
final TextFilePatch result = buildPatchHeading(basePath, beforeRevision, afterRevision);
final PatchHunk hunk = new PatchHunk(0, 0, 0, 0);
result.addHunk(hunk);
@@ -242,14 +243,14 @@ public class TextPatchBuilder {
}
private TextFilePatch buildAddedFile(final String basePath, final AirContentRevision afterRevision) throws VcsException {
- final String content = afterRevision.getContentAsString();
+ final DiffString content = DiffString.createNullable(afterRevision.getContentAsString());
if (content == null) {
throw new VcsException("Failed to fetch content for added file " + afterRevision.getPath().getPath());
}
- String[] lines = tokenize(content);
+ DiffString[] lines = tokenize(content);
TextFilePatch result = buildPatchHeading(basePath, afterRevision, afterRevision);
PatchHunk hunk = new PatchHunk(-1, -1, 0, lines.length);
- for(String line: lines) {
+ for (DiffString line : lines) {
checkCanceled();
addLineToHunk(hunk, line, PatchLine.Type.ADD);
}
@@ -258,14 +259,14 @@ public class TextPatchBuilder {
}
private TextFilePatch buildDeletedFile(String basePath, AirContentRevision beforeRevision) throws VcsException {
- final String content = beforeRevision.getContentAsString();
+ final DiffString content = DiffString.createNullable(beforeRevision.getContentAsString());
if (content == null) {
throw new VcsException("Failed to fetch old content for deleted file " + beforeRevision.getPath().getPath());
}
- String[] lines = tokenize(content);
+ DiffString[] lines = tokenize(content);
TextFilePatch result = buildPatchHeading(basePath, beforeRevision, beforeRevision);
PatchHunk hunk = new PatchHunk(0, lines.length, -1, -1);
- for(String line: lines) {
+ for (DiffString line : lines) {
checkCanceled();
addLineToHunk(hunk, line, PatchLine.Type.REMOVE);
}
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/vfs/AbstractVcsVirtualFile.java b/platform/vcs-api/src/com/intellij/openapi/vcs/vfs/AbstractVcsVirtualFile.java
index 94b7e923fa79..a28564df1722 100644
--- a/platform/vcs-api/src/com/intellij/openapi/vcs/vfs/AbstractVcsVirtualFile.java
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/vfs/AbstractVcsVirtualFile.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,20 +44,25 @@ public abstract class AbstractVcsVirtualFile extends VirtualFile {
myParent = null;
}
+ @Override
@NotNull
public VirtualFileSystem getFileSystem() {
return myFileSystem;
}
+ @Override
+ @NotNull
public String getPath() {
return myPath;
}
+ @Override
@NotNull
public String getName() {
return myName;
}
+ @Override
public String getPresentableName() {
if (myRevision == null)
return myName;
@@ -65,43 +70,53 @@ public abstract class AbstractVcsVirtualFile extends VirtualFile {
return myName + " (" + myRevision + ")";
}
+ @Override
public boolean isWritable() {
return false;
}
+ @Override
public boolean isValid() {
return true;
}
+ @Override
public VirtualFile getParent() {
return myParent;
}
+ @Override
public VirtualFile[] getChildren() {
return null;
}
+ @Override
public InputStream getInputStream() throws IOException {
return VfsUtilCore.byteStreamSkippingBOM(contentsToByteArray(), this);
}
+ @Override
@NotNull
public OutputStream getOutputStream(Object requestor, long newModificationStamp, long newTimeStamp) throws IOException {
throw new RuntimeException(VcsFileSystem.COULD_NOT_IMPLEMENT_MESSAGE);
}
+ @Override
@NotNull
public abstract byte[] contentsToByteArray() throws IOException;
+ @Override
public long getModificationStamp() {
return myModificationStamp;
}
+ @Override
public long getTimeStamp() {
return myModificationStamp;
}
+ @Override
public long getLength() {
try {
return contentsToByteArray().length;
@@ -110,6 +125,7 @@ public abstract class AbstractVcsVirtualFile extends VirtualFile {
}
}
+ @Override
public void refresh(boolean asynchronous, boolean recursive, Runnable postRunnable) {
if (postRunnable != null)
postRunnable.run();
@@ -123,6 +139,7 @@ public abstract class AbstractVcsVirtualFile extends VirtualFile {
myProcessingBeforeContentsChange = true;
try {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
public void run() {
((VcsFileSystem)getFileSystem()).fireBeforeContentsChange(this, AbstractVcsVirtualFile.this);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java
index 5b95283e1b30..2f3788ae509c 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java
@@ -146,7 +146,7 @@ public class FragmentedDiffRequestFromChange {
comparisonPolicy = ComparisonPolicy.DEFAULT;
}
final TextCompareProcessor processor = new TextCompareProcessor(comparisonPolicy);
- final ArrayList<LineFragment> lineFragments = processor.process(myOldDocument.getText(), myDocument.getText());
+ final List<LineFragment> lineFragments = processor.process(myOldDocument.getText(), myDocument.getText());
myRanges = new ArrayList<BeforeAfter<TextRange>>(lineFragments.size());
for (LineFragment lineFragment : lineFragments) {
if (!lineFragment.isEqual()) {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java
index 0f941a3a9c21..24884b4a101c 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.ex;
import com.intellij.codeInsight.hint.EditorFragmentComponent;
import com.intellij.codeInsight.hint.HintManagerImpl;
import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.diff.DiffColors;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -165,9 +166,6 @@ public class LineStatusTrackerDrawing {
group.add(new ShowLineStatusRangeDiffAction(tracker, range, editor));
group.add(new CopyLineStatusRangeAction(tracker, range));
- @SuppressWarnings("unchecked")
- final List<AnAction> actionList = (List<AnAction>)editorComponent.getClientProperty(AnAction.ourClientProperty);
-
final JComponent toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.FILEHISTORY_VIEW_TOOLBAR, group, true).getComponent();
final Color background = ((EditorEx)editor).getBackgroundColor();
@@ -218,6 +216,7 @@ public class LineStatusTrackerDrawing {
EditorFactory.getInstance().releaseEditor(uEditor);
}
+ final List<AnAction> actionList = ActionUtil.getActions(editorComponent);
final LightweightHint lightweightHint = new LightweightHint(component);
HintListener closeListener = new HintListener() {
public void hintHidden(final EventObject event) {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java
index 7711dd3ac394..e51a2a5f1abb 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java
@@ -38,6 +38,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.encoding.EncodingManager;
import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
+import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent;
import com.intellij.util.WaitForProgressToShow;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -121,7 +122,7 @@ public class VcsHistoryUtil {
diffData.setContents(createContent(project, content1, revision1, doc, charset, fileType, filePath.getPath()),
createContent(project, content2, revision2, doc, charset, fileType, filePath.getPath()));
} else {
- diffData.setContents(new FileContent(project, f1.get()), new FileContent(project, f2.get()));
+ diffData.setContents(createFileContent(project, f1.get(), revision1), createFileContent(project, f2.get(), revision2));
}
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
public void run() {
@@ -188,13 +189,22 @@ public class VcsHistoryUtil {
private static DiffContent createContent(@NotNull Project project, byte[] content1, VcsFileRevision revision, Document doc, Charset charset, FileType fileType, String filePath) {
if (isCurrent(revision) && (doc != null)) { return new DocumentContent(project, doc); }
+ if (isEmpty(revision)) { return SimpleContent.createEmpty(); }
return new BinaryContent(project, content1, charset, fileType, filePath);
}
+ private static DiffContent createFileContent(@NotNull Project project, VirtualFile file, VcsFileRevision revision) {
+ if (isEmpty(revision)) { return SimpleContent.createEmpty(); }
+ return new FileContent(project, file);
+ }
+
private static boolean isCurrent(VcsFileRevision revision) {
return revision instanceof CurrentRevision;
}
+ private static boolean isEmpty(VcsFileRevision revision) {
+ return revision == null || VcsFileRevision.NULL.equals(revision);
+ }
/**
* Shows difference between two revisions of a file in a diff tool.
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 26a26725fd90..a3a520376909 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
@@ -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,12 +79,12 @@ class VcsLogHashMap implements Disposable {
private static class MyHashKeyDescriptor implements KeyDescriptor<Hash> {
@Override
- public void save(DataOutput out, Hash value) throws IOException {
+ public void save(@NotNull DataOutput out, Hash value) throws IOException {
out.writeUTF(value.asString());
}
@Override
- public Hash read(DataInput in) throws IOException {
+ public Hash read(@NotNull DataInput in) throws IOException {
return HashImpl.build(in.readUTF());
}
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java
index 6a116d23387a..4f205e3f2eed 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java
@@ -23,6 +23,8 @@ import com.intellij.execution.ui.RunnerLayoutUi;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
+import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.frame.XValueMarkerProvider;
import com.intellij.xdebugger.stepping.XSmartStepIntoHandler;
import com.intellij.xdebugger.ui.XDebugTabLayouter;
@@ -226,4 +228,9 @@ public abstract class XDebugProcess {
return false;
}
+ @Nullable
+ public XDebuggerEvaluator getEvaluator() {
+ XStackFrame frame = getSession().getCurrentStackFrame();
+ return frame == null ? null : frame.getEvaluator();
+ }
}
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
index 534545847f42..be71aac98d1e 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
@@ -83,6 +83,7 @@ public interface XDebugSession extends AbstractDebuggerSession {
/**
* @deprecated use {@link #setCurrentStackFrame(com.intellij.xdebugger.frame.XExecutionStack, com.intellij.xdebugger.frame.XStackFrame)} instead
*/
+ @SuppressWarnings("UnusedDeclaration")
void setCurrentStackFrame(@NotNull XStackFrame frame);
/**
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java
index a6b07b3e4173..676fb3f32826 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java
@@ -100,4 +100,11 @@ public abstract class XLineBreakpointType<P extends XBreakpointProperties> exten
public Icon getTemporaryIcon() {
return AllIcons.Debugger.Db_temporary_breakpoint;
}
+
+ /**
+ * Higher priority wins if several types available for the line(s)
+ */
+ public int getPriority() {
+ return 0;
+ }
}
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java
index 1cf23c566d0b..7130b7747c25 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java
@@ -115,7 +115,7 @@ public abstract class XDebuggerEvaluator {
* @param offset offset
* @param sideEffectsAllowed if this parameter is false, the expression should not have any side effects when evaluated
* (such expressions are evaluated in quick popups)
- * @return pair of text range of expression (to display as link) and actual expression to evaluate (optional, could be null)
+ * @return pair of text range of expression (to highlight as link) and actual expression to evaluate (optional, could be null)
*/
@Nullable
public Pair<TextRange, String> getExpressionAtOffset(@NotNull Project project, @NotNull Document document, int offset, boolean sideEffectsAllowed) {
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XStackFrame.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XStackFrame.java
index eaa642037d95..ba5d5f37b1cc 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XStackFrame.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XStackFrame.java
@@ -22,6 +22,7 @@ import com.intellij.ui.SimpleTextAttributes;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -63,7 +64,7 @@ public abstract class XStackFrame extends XValueContainer {
* Customize presentation of the stack frame in frames list
* @param component component
*/
- public void customizePresentation(ColoredTextContainer component) {
+ public void customizePresentation(@NotNull ColoredTextContainer component) {
XSourcePosition position = getSourcePosition();
if (position != null) {
component.append(position.getFile().getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/PsiBackedSmartStepIntoVariant.java b/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/PsiBackedSmartStepIntoVariant.java
index f2728161ef13..d17f8e01271d 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/PsiBackedSmartStepIntoVariant.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/PsiBackedSmartStepIntoVariant.java
@@ -36,6 +36,7 @@ public class PsiBackedSmartStepIntoVariant<T extends PsiNamedElement & Navigatio
assert myPresentation != null: "Invalid presentation:" + myElement;
}
+ @Override
public String getText() {
String location = myPresentation.getLocationString();
return myPresentation.getPresentableText() + (location != null ? " " + location: "");
@@ -46,6 +47,7 @@ public class PsiBackedSmartStepIntoVariant<T extends PsiNamedElement & Navigatio
return myPresentation.getIcon(false);
}
+ @NotNull
public T getElement() {
return myElement;
}
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java b/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java
index 46dcaa236651..56b098de99f0 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java
@@ -40,7 +40,7 @@ public abstract class XSmartStepIntoHandler<Variant extends XSmartStepIntoVarian
* when <code>variant</code> function/method is reached
* @param variant selected variant
*/
- public abstract void startStepInto(Variant variant);
+ public abstract void startStepInto(@NotNull Variant variant);
/**
* @return title for popup which will be shown to select method/function
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java
index 42bee651e742..82c052240673 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java
@@ -15,11 +15,15 @@
*/
package com.intellij.xdebugger.impl;
+import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.AbstractDebuggerSession;
-import com.intellij.xdebugger.impl.actions.*;
+import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
+import com.intellij.xdebugger.impl.actions.DebuggerToggleActionHandler;
+import com.intellij.xdebugger.impl.actions.EditBreakpointActionHandler;
+import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider;
import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
import com.intellij.xdebugger.impl.settings.DebuggerSettingsPanelProvider;
@@ -32,6 +36,19 @@ import org.jetbrains.annotations.Nullable;
public abstract class DebuggerSupport {
private static final ExtensionPointName<DebuggerSupport> EXTENSION_POINT = ExtensionPointName.create("com.intellij.xdebugger.debuggerSupport");
+ protected static final class DisabledActionHandler extends DebuggerActionHandler {
+ public static final DisabledActionHandler INSTANCE = new DisabledActionHandler();
+
+ @Override
+ public void perform(@NotNull Project project, AnActionEvent event) {
+ }
+
+ @Override
+ public boolean isEnabled(@NotNull Project project, AnActionEvent event) {
+ return false;
+ }
+ }
+
@NotNull
public static DebuggerSupport[] getDebuggerSupports() {
return Extensions.getExtensions(EXTENSION_POINT);
@@ -95,6 +112,10 @@ public abstract class DebuggerSupport {
@NotNull
public abstract DebuggerActionHandler getAddToWatchesActionHandler();
+ public DebuggerActionHandler getEvaluateInConsoleActionHandler() {
+ return DisabledActionHandler.INSTANCE;
+ }
+
@NotNull
public abstract DebuggerToggleActionHandler getMuteBreakpointsHandler();
@@ -116,6 +137,6 @@ public abstract class DebuggerSupport {
return support;
}
}
- return null;
+ throw new IllegalStateException();
}
}
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 ea407a2cfcd4..337f6fe28a89 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
@@ -51,6 +51,7 @@ import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.ui.AppUIUtil;
import com.intellij.util.EventDispatcher;
import com.intellij.util.SmartList;
+import com.intellij.util.containers.SmartHashSet;
import com.intellij.util.ui.UIUtil;
import com.intellij.xdebugger.*;
import com.intellij.xdebugger.breakpoints.*;
@@ -67,6 +68,7 @@ import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
import com.intellij.xdebugger.stepping.XSmartStepIntoHandler;
import com.intellij.xdebugger.stepping.XSmartStepIntoVariant;
+import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -86,8 +88,8 @@ public class XDebugSessionImpl implements XDebugSession {
false);
private XDebugProcess myDebugProcess;
private final Map<XBreakpoint<?>, CustomizedBreakpointPresentation> myRegisteredBreakpoints =
- new HashMap<XBreakpoint<?>, CustomizedBreakpointPresentation>();
- private final Set<XBreakpoint<?>> myInactiveSlaveBreakpoints = new HashSet<XBreakpoint<?>>();
+ new THashMap<XBreakpoint<?>, CustomizedBreakpointPresentation>();
+ private final Set<XBreakpoint<?>> myInactiveSlaveBreakpoints = new SmartHashSet<XBreakpoint<?>>();
private boolean myBreakpointsMuted;
private boolean myBreakpointsDisabled;
private final XDebuggerManagerImpl myDebuggerManager;
@@ -329,6 +331,7 @@ public class XDebugSessionImpl implements XDebugSession {
return myValueMarkers;
}
+ @SuppressWarnings("unchecked") //need to compile under 1.8, please do not remove before checking
private static XBreakpointType getBreakpointTypeClass(final XBreakpointHandler handler) {
return XDebuggerUtil.getInstance().findBreakpointType(handler.getBreakpointTypeClass());
}
@@ -351,12 +354,9 @@ public class XDebugSessionImpl implements XDebugSession {
handler.registerBreakpoint(b);
}
if (!register) {
- boolean removed = false;
+ boolean removed;
synchronized (myRegisteredBreakpoints) {
- if (myRegisteredBreakpoints.containsKey(b)) {
- myRegisteredBreakpoints.remove(b);
- removed = true;
- }
+ removed = myRegisteredBreakpoints.remove(b) != null;
}
if (removed) {
handler.unregisterBreakpoint(b, temporary);
@@ -780,7 +780,7 @@ public class XDebugSessionImpl implements XDebugSession {
myBreakpointsDisabled = false;
new ReadAction() {
@Override
- protected void run(final Result result) {
+ protected void run(@NotNull Result result) {
processAllBreakpoints(true, false);
}
}.execute();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java
index c56f2c723261..fbfe184a5f3f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java
@@ -50,11 +50,14 @@ public class XDebuggerSupport extends DebuggerSupport {
private final XDebuggerEvaluateActionHandler myEvaluateHandler;
private final XQuickEvaluateHandler myQuickEvaluateHandler;
private final XDebuggerSettingsPanelProviderImpl mySettingsPanelProvider;
+
private final XAddToWatchesFromEditorActionHandler myAddToWatchesActionHandler;
+ private final DebuggerActionHandler myEvaluateInConsoleActionHandler = new XEvaluateInConsoleFromEditorActionHandler();
+
private final DebuggerToggleActionHandler myMuteBreakpointsHandler;
private final DebuggerActionHandler mySmartStepIntoHandler;
private final XMarkObjectActionHandler myMarkObjectActionHandler;
- private final EditBreakpointActionHandler myEditBreakpointActoinHandler;
+ private final EditBreakpointActionHandler myEditBreakpointActionHandler;
public XDebuggerSupport() {
myBreakpointPanelProvider = new XBreakpointPanelProvider();
@@ -62,26 +65,31 @@ public class XDebuggerSupport extends DebuggerSupport {
myToggleTemporaryLineBreakpointActionHandler = new XToggleLineBreakpointActionHandler(true);
myAddToWatchesActionHandler = new XAddToWatchesFromEditorActionHandler();
myStepOverHandler = new XDebuggerSuspendedActionHandler() {
+ @Override
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
session.stepOver(false);
}
};
myStepIntoHandler = new XDebuggerSuspendedActionHandler() {
+ @Override
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
session.stepInto();
}
};
myStepOutHandler = new XDebuggerSuspendedActionHandler() {
+ @Override
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
session.stepOut();
}
};
myForceStepOverHandler = new XDebuggerSuspendedActionHandler() {
+ @Override
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
session.stepOver(true);
}
};
myForceStepIntoHandler = new XDebuggerSuspendedActionHandler() {
+ @Override
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
session.forceStepInto();
}
@@ -90,16 +98,19 @@ public class XDebuggerSupport extends DebuggerSupport {
myRunToCursorHandler = new XDebuggerRunToCursorActionHandler(false);
myForceRunToCursor = new XDebuggerRunToCursorActionHandler(true);
myResumeHandler = new XDebuggerActionHandler() {
+ @Override
protected boolean isEnabled(@NotNull final XDebugSession session, final DataContext dataContext) {
return session.isPaused();
}
+ @Override
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
session.resume();
}
};
myPauseHandler = new XDebuggerPauseActionHandler();
myShowExecutionPointHandler = new XDebuggerSuspendedActionHandler() {
+ @Override
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
session.showExecutionPoint();
}
@@ -109,64 +120,76 @@ public class XDebuggerSupport extends DebuggerSupport {
myQuickEvaluateHandler = new XQuickEvaluateHandler();
mySettingsPanelProvider = new XDebuggerSettingsPanelProviderImpl();
myMarkObjectActionHandler = new XMarkObjectActionHandler();
- myEditBreakpointActoinHandler = new XDebuggerEditBreakpointActionHandler();
+ myEditBreakpointActionHandler = new XDebuggerEditBreakpointActionHandler();
}
+ @Override
@NotNull
public BreakpointPanelProvider<?> getBreakpointPanelProvider() {
return myBreakpointPanelProvider;
}
+ @Override
@NotNull
public DebuggerActionHandler getStepOverHandler() {
return myStepOverHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getStepIntoHandler() {
return myStepIntoHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getSmartStepIntoHandler() {
return mySmartStepIntoHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getStepOutHandler() {
return myStepOutHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getForceStepOverHandler() {
return myForceStepOverHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getForceStepIntoHandler() {
return myForceStepIntoHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getRunToCursorHandler() {
return myRunToCursorHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getForceRunToCursorHandler() {
return myForceRunToCursor;
}
+ @Override
@NotNull
public DebuggerActionHandler getResumeActionHandler() {
return myResumeHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getPauseHandler() {
return myPauseHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getToggleLineBreakpointHandler() {
return myToggleLineBreakpointActionHandler;
@@ -178,16 +201,19 @@ public class XDebuggerSupport extends DebuggerSupport {
return myToggleTemporaryLineBreakpointActionHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getShowExecutionPointHandler() {
return myShowExecutionPointHandler;
}
+ @Override
@NotNull
public DebuggerActionHandler getEvaluateHandler() {
return myEvaluateHandler;
}
+ @Override
@NotNull
public QuickEvaluateHandler getQuickEvaluateHandler() {
return myQuickEvaluateHandler;
@@ -200,6 +226,13 @@ public class XDebuggerSupport extends DebuggerSupport {
}
@NotNull
+ @Override
+ public DebuggerActionHandler getEvaluateInConsoleActionHandler() {
+ return myEvaluateInConsoleActionHandler;
+ }
+
+ @Override
+ @NotNull
public DebuggerToggleActionHandler getMuteBreakpointsHandler() {
return myMuteBreakpointsHandler;
}
@@ -218,12 +251,12 @@ public class XDebuggerSupport extends DebuggerSupport {
@NotNull
@Override
public EditBreakpointActionHandler getEditBreakpointAction() {
- return myEditBreakpointActoinHandler;
+ return myEditBreakpointActionHandler;
}
+ @Override
@NotNull
public DebuggerSettingsPanelProvider getSettingsPanelProvider() {
return mySettingsPanelProvider;
}
-
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
index 76a360f748ab..191b8f2b1cfb 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
@@ -75,12 +75,15 @@ public class XDebuggerUtilImpl extends XDebuggerUtil {
@Override
public void toggleLineBreakpoint(@NotNull final Project project, @NotNull final VirtualFile file, final int line, boolean temporary) {
+ XLineBreakpointType<?> typeWinner = null;
for (XLineBreakpointType<?> type : getLineBreakpointTypes()) {
- if (type.canPutAt(file, line, project)) {
- toggleLineBreakpoint(project, type, file, line, temporary);
- return;
+ if (type.canPutAt(file, line, project) && (typeWinner == null || type.getPriority() > typeWinner.getPriority())) {
+ typeWinner = type;
}
}
+ if (typeWinner != null) {
+ toggleLineBreakpoint(project, typeWinner, file, line, temporary);
+ }
}
@Override
@@ -222,34 +225,34 @@ public class XDebuggerUtilImpl extends XDebuggerUtil {
@Override
public void iterateLine(@NotNull Project project, @NotNull Document document, int line, @NotNull Processor<PsiElement> processor) {
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
- if (file == null) return;
+ if (file == null) {
+ return;
+ }
int lineStart;
int lineEnd;
-
try {
lineStart = document.getLineStartOffset(line);
lineEnd = document.getLineEndOffset(line);
}
- catch (IndexOutOfBoundsException e) {
+ catch (IndexOutOfBoundsException ignored) {
return;
}
PsiElement element;
-
- int off = lineStart;
- while (off < lineEnd) {
- element = file.findElementAt(off);
+ int offset = lineStart;
+ while (offset < lineEnd) {
+ element = file.findElementAt(offset);
if (element != null) {
if (!processor.process(element)) {
return;
}
else {
- off = element.getTextRange().getEndOffset();
+ offset = element.getTextRange().getEndOffset();
}
}
else {
- off++;
+ offset++;
}
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/AddToWatchesAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/AddToWatchesAction.java
index 33bfc5a33e02..c93496be2699 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/AddToWatchesAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/AddToWatchesAction.java
@@ -18,10 +18,7 @@ package com.intellij.xdebugger.impl.actions;
import com.intellij.xdebugger.impl.DebuggerSupport;
import org.jetbrains.annotations.NotNull;
-/**
- * @author nik
- */
-public class AddToWatchesAction extends XDebuggerActionBase {
+final class AddToWatchesAction extends XDebuggerActionBase {
public AddToWatchesAction() {
super(true);
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateAction.java
index 39e594902ef8..ea17644e53f0 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateAction.java
@@ -15,17 +15,18 @@
*/
package com.intellij.xdebugger.impl.actions;
-import org.jetbrains.annotations.NotNull;
import com.intellij.xdebugger.impl.DebuggerSupport;
+import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
-public class EvaluateAction extends XDebuggerActionBase {
+final class EvaluateAction extends XDebuggerActionBase {
public EvaluateAction() {
super(true);
}
+ @Override
@NotNull
protected DebuggerActionHandler getHandler(@NotNull final DebuggerSupport debuggerSupport) {
return debuggerSupport.getEvaluateHandler();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateInConsoleAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateInConsoleAction.java
new file mode 100644
index 000000000000..ebfbb94ed5da
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateInConsoleAction.java
@@ -0,0 +1,31 @@
+/*
+ * 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 com.intellij.xdebugger.impl.actions;
+
+import com.intellij.xdebugger.impl.DebuggerSupport;
+import org.jetbrains.annotations.NotNull;
+
+final class EvaluateInConsoleAction extends XDebuggerActionBase {
+ public EvaluateInConsoleAction() {
+ super(true);
+ }
+
+ @NotNull
+ @Override
+ protected DebuggerActionHandler getHandler(@NotNull DebuggerSupport debuggerSupport) {
+ return debuggerSupport.getEvaluateInConsoleActionHandler();
+ }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/QuickEvaluateAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/QuickEvaluateAction.java
index 25e1b012eba0..be54d591d378 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/QuickEvaluateAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/QuickEvaluateAction.java
@@ -40,6 +40,7 @@ public class QuickEvaluateAction extends XDebuggerActionBase {
super(true);
}
+ @Override
@NotNull
protected DebuggerActionHandler getHandler(@NotNull final DebuggerSupport debuggerSupport) {
return new QuickEvaluateHandlerWrapper(debuggerSupport.getQuickEvaluateHandler());
@@ -52,6 +53,7 @@ public class QuickEvaluateAction extends XDebuggerActionBase {
myHandler = handler;
}
+ @Override
public void perform(@NotNull final Project project, final AnActionEvent event) {
Editor editor = event.getData(CommonDataKeys.EDITOR);
if (editor != null) {
@@ -61,11 +63,16 @@ public class QuickEvaluateAction extends XDebuggerActionBase {
}
}
+ @Override
public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) {
- if (!myHandler.isEnabled(project)) return false;
+ if (!myHandler.isEnabled(project)) {
+ return false;
+ }
Editor editor = event.getData(CommonDataKeys.EDITOR);
- if (editor == null) return false;
+ if (editor == null) {
+ return false;
+ }
InputEvent inputEvent = event.getInputEvent();
if (inputEvent instanceof MouseEvent && inputEvent.isAltDown()) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ResumeAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ResumeAction.java
index c669ec2b3298..011c41b209e1 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ResumeAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ResumeAction.java
@@ -19,7 +19,7 @@ import com.intellij.execution.actions.ChooseDebugConfigurationPopupAction;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.AbstractDebuggerSession;
import com.intellij.xdebugger.impl.DebuggerSupport;
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
-public class ResumeAction extends XDebuggerActionBase {
+public class ResumeAction extends XDebuggerActionBase implements DumbAware {
@Override
protected boolean isEnabled(AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ShowExecutionPointAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ShowExecutionPointAction.java
index a00e2618c5a5..12def64e36ef 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ShowExecutionPointAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ShowExecutionPointAction.java
@@ -15,13 +15,14 @@
*/
package com.intellij.xdebugger.impl.actions;
-import org.jetbrains.annotations.NotNull;
import com.intellij.xdebugger.impl.DebuggerSupport;
+import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class ShowExecutionPointAction extends XDebuggerActionBase {
+ @Override
@NotNull
protected DebuggerActionHandler getHandler(@NotNull final DebuggerSupport debuggerSupport) {
return debuggerSupport.getShowExecutionPointHandler();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/SmartStepIntoAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/SmartStepIntoAction.java
index f886f1f1b80a..adc2589b645c 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/SmartStepIntoAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/SmartStepIntoAction.java
@@ -15,13 +15,14 @@
*/
package com.intellij.xdebugger.impl.actions;
-import org.jetbrains.annotations.NotNull;
import com.intellij.xdebugger.impl.DebuggerSupport;
+import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
-public class SmartStepIntoAction extends XDebuggerActionBase {
+final class SmartStepIntoAction extends XDebuggerActionBase {
+ @Override
@NotNull
protected DebuggerActionHandler getHandler(@NotNull final DebuggerSupport debuggerSupport) {
return debuggerSupport.getSmartStepIntoHandler();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActionBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActionBase.java
index 8ed04300d973..5e3a6c100646 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActionBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActionBase.java
@@ -39,8 +39,7 @@ public abstract class XDebuggerActionBase extends AnAction implements AnAction.T
Presentation presentation = event.getPresentation();
boolean hidden = isHidden(event);
if (hidden) {
- presentation.setEnabled(false);
- presentation.setVisible(false);
+ presentation.setEnabledAndVisible(false);
return;
}
@@ -100,7 +99,7 @@ public abstract class XDebuggerActionBase extends AnAction implements AnAction.T
}
protected boolean isHidden(AnActionEvent event) {
- final Project project = event.getData(CommonDataKeys.PROJECT);
+ final Project project = event.getProject();
if (project != null) {
for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) {
if (!getHandler(support).isHidden(project, event)) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerSuspendedActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerSuspendedActionHandler.java
index 70ecabddcdea..0137fac87ac2 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerSuspendedActionHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerSuspendedActionHandler.java
@@ -15,16 +15,16 @@
*/
package com.intellij.xdebugger.impl.actions;
+import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.impl.actions.handlers.XDebuggerActionHandler;
-import com.intellij.openapi.actionSystem.DataContext;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public abstract class XDebuggerSuspendedActionHandler extends XDebuggerActionHandler {
-
+ @Override
protected boolean isEnabled(final @NotNull XDebugSession session, final DataContext dataContext) {
return session.isSuspended();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java
index 3b52fa58bf7b..b1aac452c60f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java
@@ -20,7 +20,7 @@ import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.xdebugger.XDebugSession;
-import com.intellij.xdebugger.frame.XStackFrame;
+import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -35,17 +35,17 @@ public class XAddToWatchesFromEditorActionHandler extends XDebuggerActionHandler
}
@Nullable
- private static String getTextToEvaluate(DataContext dataContext, XDebugSession session) {
+ protected static String getTextToEvaluate(DataContext dataContext, XDebugSession session) {
final Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
if (editor == null) {
return null;
}
String text = editor.getSelectionModel().getSelectedText();
- if (text == null && session.isSuspended()) {
- final XStackFrame stackFrame = session.getCurrentStackFrame();
- if (stackFrame != null) {
- text = XDebuggerEvaluateActionHandler.getExpressionText(stackFrame.getEvaluator(), editor.getProject(), editor);
+ if (text == null) {
+ XDebuggerEvaluator evaluator = session.getDebugProcess().getEvaluator();
+ if (evaluator != null) {
+ text = XDebuggerEvaluateActionHandler.getExpressionText(evaluator, editor.getProject(), editor);
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerActionHandler.java
index 3ac02a62dbdb..fa079b3ff707 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerActionHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerActionHandler.java
@@ -15,19 +15,19 @@
*/
package com.intellij.xdebugger.impl.actions.handlers;
-import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
-import com.intellij.xdebugger.XDebuggerManager;
-import com.intellij.xdebugger.XDebugSession;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.project.Project;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.XDebuggerManager;
+import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public abstract class XDebuggerActionHandler extends DebuggerActionHandler {
-
+ @Override
public void perform(@NotNull final Project project, final AnActionEvent event) {
XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
if (session != null) {
@@ -35,6 +35,7 @@ public abstract class XDebuggerActionHandler extends DebuggerActionHandler {
}
}
+ @Override
public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) {
XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
return session != null && isEnabled(session, event.getDataContext());
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java
index d892acaf0f44..1a24b3074216 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java
@@ -28,7 +28,6 @@ import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.frame.XValue;
-import com.intellij.xdebugger.impl.actions.XDebuggerSuspendedActionHandler;
import com.intellij.xdebugger.impl.evaluate.XDebuggerEvaluationDialog;
import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase;
import org.jetbrains.annotations.NotNull;
@@ -37,14 +36,15 @@ import org.jetbrains.annotations.Nullable;
/**
* @author nik
*/
-public class XDebuggerEvaluateActionHandler extends XDebuggerSuspendedActionHandler {
+public class XDebuggerEvaluateActionHandler extends XDebuggerActionHandler {
@Override
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
XDebuggerEditorsProvider editorsProvider = session.getDebugProcess().getEditorsProvider();
XStackFrame stackFrame = session.getCurrentStackFrame();
- if (stackFrame == null) return;
- final XDebuggerEvaluator evaluator = stackFrame.getEvaluator();
- if (evaluator == null) return;
+ final XDebuggerEvaluator evaluator = session.getDebugProcess().getEvaluator();
+ if (evaluator == null) {
+ return;
+ }
@Nullable Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
@@ -64,7 +64,7 @@ public class XDebuggerEvaluateActionHandler extends XDebuggerSuspendedActionHand
text = value.getEvaluationExpression();
}
}
- new XDebuggerEvaluationDialog(session, editorsProvider, evaluator, StringUtil.notNullize(text), stackFrame.getSourcePosition()).show();
+ new XDebuggerEvaluationDialog(session, editorsProvider, evaluator, StringUtil.notNullize(text), stackFrame == null ? null : stackFrame.getSourcePosition()).show();
}
@Nullable
@@ -86,11 +86,6 @@ public class XDebuggerEvaluateActionHandler extends XDebuggerSuspendedActionHand
@Override
protected boolean isEnabled(final @NotNull XDebugSession session, final DataContext dataContext) {
- if (!super.isEnabled(session, dataContext)) {
- return false;
- }
-
- XStackFrame stackFrame = session.getCurrentStackFrame();
- return stackFrame != null && stackFrame.getEvaluator() != null;
+ return session.getDebugProcess().getEvaluator() != null;
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
index 4a933b794aac..6d09b8fd3128 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
@@ -15,21 +15,21 @@
*/
package com.intellij.xdebugger.impl.actions.handlers;
-import org.jetbrains.annotations.NotNull;
-import com.intellij.xdebugger.XDebugSession;
-import com.intellij.xdebugger.XSourcePosition;
-import com.intellij.xdebugger.stepping.XSmartStepIntoHandler;
-import com.intellij.xdebugger.stepping.XSmartStepIntoVariant;
-import com.intellij.xdebugger.impl.actions.XDebuggerSuspendedActionHandler;
-import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.ui.awt.RelativePoint;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.XSourcePosition;
+import com.intellij.xdebugger.impl.actions.XDebuggerSuspendedActionHandler;
+import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
+import com.intellij.xdebugger.stepping.XSmartStepIntoHandler;
+import com.intellij.xdebugger.stepping.XSmartStepIntoVariant;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.List;
@@ -39,10 +39,12 @@ import java.util.List;
*/
public class XDebuggerSmartStepIntoHandler extends XDebuggerSuspendedActionHandler {
+ @Override
protected boolean isEnabled(@NotNull XDebugSession session, DataContext dataContext) {
return super.isEnabled(session, dataContext) && session.getDebugProcess().getSmartStepIntoHandler() != null;
}
+ @Override
protected void perform(@NotNull XDebugSession session, DataContext dataContext) {
final XSmartStepIntoHandler<?> handler = session.getDebugProcess().getSmartStepIntoHandler();
final XSourcePosition position = session.getCurrentPosition();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XEvaluateInConsoleFromEditorActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XEvaluateInConsoleFromEditorActionHandler.java
new file mode 100644
index 000000000000..fb5f3d7d8b66
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XEvaluateInConsoleFromEditorActionHandler.java
@@ -0,0 +1,86 @@
+package com.intellij.xdebugger.impl.actions.handlers;
+
+import com.intellij.execution.console.ConsoleExecuteAction;
+import com.intellij.execution.console.LanguageConsoleView;
+import com.intellij.execution.ui.ConsoleView;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.ex.ActionUtil;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+public class XEvaluateInConsoleFromEditorActionHandler extends XAddToWatchesFromEditorActionHandler {
+ @Override
+ protected boolean isEnabled(@NotNull XDebugSession session, DataContext dataContext) {
+ return super.isEnabled(session, dataContext) && getConsoleExecuteAction(session) != null;
+ }
+
+ @Nullable
+ private static ConsoleExecuteAction getConsoleExecuteAction(@NotNull XDebugSession session) {
+ return getConsoleExecuteAction(session.getConsoleView());
+ }
+
+ @Nullable
+ public static ConsoleExecuteAction getConsoleExecuteAction(@Nullable ConsoleView consoleView) {
+ if (!(consoleView instanceof LanguageConsoleView)) {
+ return null;
+ }
+
+ List<AnAction> actions = ActionUtil.getActions(((LanguageConsoleView)consoleView).getConsole().getConsoleEditor().getComponent());
+ ConsoleExecuteAction action = ContainerUtil.findInstance(actions, ConsoleExecuteAction.class);
+ return action == null || !action.isEnabled() ? null : action;
+ }
+
+ @Override
+ protected void perform(@NotNull XDebugSession session, DataContext dataContext) {
+ Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
+ if (editor == null || !(editor instanceof EditorEx)) {
+ return;
+ }
+
+ int selectionStart = editor.getSelectionModel().getSelectionStart();
+ int selectionEnd = editor.getSelectionModel().getSelectionEnd();
+ String text;
+ TextRange range;
+ if (selectionStart != selectionEnd) {
+ range = new TextRange(selectionStart, selectionEnd);
+ text = editor.getDocument().getText(range);
+ }
+ else {
+ XDebuggerEvaluator evaluator = session.getDebugProcess().getEvaluator();
+ if (evaluator != null) {
+ Pair<TextRange, String> expressionInfo = evaluator.getExpressionAtOffset(session.getProject(), editor.getDocument(), selectionStart, true);
+ if (expressionInfo == null) {
+ return;
+ }
+
+ // todo check - is it wrong in case of not-null expressionInfo.second - copied (to console history document) text (text range) could be not correct statement?
+ range = expressionInfo.first;
+ text = XDebuggerEvaluateActionHandler.getExpressionText(expressionInfo, editor.getDocument());
+ }
+ else {
+ return;
+ }
+ }
+
+ if (StringUtil.isEmptyOrSpaces(text)) {
+ return;
+ }
+
+ ConsoleExecuteAction action = getConsoleExecuteAction(session);
+ if (action != null) {
+ action.execute(range, text, (EditorEx)editor);
+ }
+ }
+} \ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XToggleLineBreakpointActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XToggleLineBreakpointActionHandler.java
index 03ae0184ec22..e100741566ac 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XToggleLineBreakpointActionHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XToggleLineBreakpointActionHandler.java
@@ -15,10 +15,12 @@
*/
package com.intellij.xdebugger.impl.actions.handlers;
+import com.intellij.codeInsight.folding.impl.FoldingUtil;
import com.intellij.codeInsight.folding.impl.actions.ExpandRegionAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.xdebugger.XDebuggerUtil;
@@ -63,20 +65,42 @@ public class XToggleLineBreakpointActionHandler extends DebuggerActionHandler {
XSourcePosition position = XDebuggerUtilImpl.getCaretPosition(project, event.getDataContext());
if (position == null) return;
- ExpandRegionAction.expandRegionAtCaret(project, event.getData(CommonDataKeys.EDITOR));
+ Editor editor = event.getData(CommonDataKeys.EDITOR);
+
+ // for folded text check each line and find out type with the biggest priority
+ int lineStart = position.getLine();
+ int linesEnd = lineStart;
+ FoldRegion region = FoldingUtil.findFoldRegionStartingAtLine(editor, lineStart);
+ if (region != null && !region.isExpanded()) {
+ linesEnd = region.getDocument().getLineNumber(region.getEndOffset());
+ }
- int line = position.getLine();
VirtualFile file = position.getFile();
final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
- for (XLineBreakpointType<?> type : XDebuggerUtil.getInstance().getLineBreakpointTypes()) {
- final XLineBreakpoint<? extends XBreakpointProperties> breakpoint = breakpointManager.findBreakpointAtLine(type, file, line);
- if (breakpoint != null && myTemporary && !breakpoint.isTemporary()) {
- breakpoint.setTemporary(true);
- } else if (type.canPutAt(file, line, project) || breakpoint != null) {
- XDebuggerUtil.getInstance().toggleLineBreakpoint(project, type, file, line, myTemporary);
- return;
+ XLineBreakpointType<?>[] lineTypes = XDebuggerUtil.getInstance().getLineBreakpointTypes();
+ XLineBreakpointType<?> typeWinner = null;
+ int lineWinner = -1;
+ for (int line = lineStart; line <= linesEnd; line++) {
+ for (XLineBreakpointType<?> type : lineTypes) {
+ final XLineBreakpoint<? extends XBreakpointProperties> breakpoint = breakpointManager.findBreakpointAtLine(type, file, line);
+ if (breakpoint != null && myTemporary && !breakpoint.isTemporary()) {
+ breakpoint.setTemporary(true);
+ } else if (type.canPutAt(file, line, project) || breakpoint != null) {
+ if (typeWinner == null || type.getPriority() > typeWinner.getPriority()) {
+ typeWinner = type;
+ lineWinner = line;
+ }
+ }
}
}
- }
+ if (typeWinner != null) {
+ XDebuggerUtil.getInstance().toggleLineBreakpoint(project, typeWinner, file, lineWinner, myTemporary);
+ }
+
+ ExpandRegionAction.expandRegionAtCaret(project, editor);
+ if (editor != null && lineStart != lineWinner) {
+ editor.getCaretModel().moveToOffset(editor.getDocument().getLineStartOffset(lineWinner));
+ }
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java
index 530fb995aae9..5f95c73ed635 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java
@@ -15,10 +15,7 @@
*/
package com.intellij.xdebugger.impl.breakpoints;
-import com.intellij.util.xmlb.annotations.Attribute;
-import com.intellij.util.xmlb.annotations.Property;
-import com.intellij.util.xmlb.annotations.Tag;
-import com.intellij.util.xmlb.annotations.Transient;
+import com.intellij.util.xmlb.annotations.*;
import com.intellij.xdebugger.breakpoints.SuspendPolicy;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
@@ -36,8 +33,8 @@ public class BreakpointState<B extends XBreakpoint<P>, P extends XBreakpointProp
private Element myPropertiesElement;
private SuspendPolicy mySuspendPolicy = SuspendPolicy.ALL;
private boolean myLogMessage;
- private String myLogExpression;
- private String myCondition;
+ private LogExpression myLogExpression;
+ private Condition myCondition;
private XBreakpointDependencyState myDependencyState;
private long myTimeStamp;
@@ -104,22 +101,52 @@ public class BreakpointState<B extends XBreakpoint<P>, P extends XBreakpointProp
myLogMessage = logMessage;
}
- @Tag("log-expression")
+ @Transient
public String getLogExpression() {
+ return myLogExpression != null ? myLogExpression.myExpression : null;
+ }
+
+ public void setLogExpression(String expression) {
+ if (expression != null) {
+ myLogExpression = new LogExpression();
+ myLogExpression.myExpression = expression;
+ }
+ else {
+ myLogExpression = null;
+ }
+ }
+
+ @Property(surroundWithTag = false)
+ public LogExpression getLogExpressionObject() {
return myLogExpression;
}
- public void setLogExpression(final String logExpression) {
- myLogExpression = logExpression;
+ public void setLogExpressionObject(final LogExpression logExpression) {
+ setLogExpression(logExpression.myOldExpression != null ? logExpression.myOldExpression : logExpression.myExpression);
}
- @Tag("condition")
+ @Transient
public String getCondition() {
+ return myCondition != null ? myCondition.myExpression : null;
+ }
+
+ public void setCondition(String condition) {
+ if (condition != null) {
+ myCondition = new Condition();
+ myCondition.myExpression = condition;
+ }
+ else {
+ myCondition = null;
+ }
+ }
+
+ @Property(surroundWithTag = false)
+ public Condition getConditionObject() {
return myCondition;
}
- public void setCondition(final String condition) {
- myCondition = condition;
+ public void setConditionObject(final Condition condition) {
+ setCondition(condition.myOldExpression != null ? condition.myOldExpression : condition.myExpression);
}
@Property(surroundWithTag = false)
@@ -142,4 +169,24 @@ public class BreakpointState<B extends XBreakpoint<P>, P extends XBreakpointProp
public void setTimeStamp(long timeStamp) {
myTimeStamp = timeStamp;
}
+
+ void applyDefaults(BreakpointState state) {
+ state.mySuspendPolicy = mySuspendPolicy;
+ }
+
+ @Tag("condition")
+ public static class Condition {
+ @Attribute("expression")
+ public String myExpression;
+ @Text
+ public String myOldExpression;
+ }
+
+ @Tag("log-expression")
+ public static class LogExpression {
+ @Attribute("expression")
+ public String myExpression;
+ @Text
+ public String myOldExpression;
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointsFavoriteListProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointsFavoriteListProvider.java
index 03adc64be2ad..a2a76c84bc18 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointsFavoriteListProvider.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointsFavoriteListProvider.java
@@ -52,7 +52,6 @@ public class BreakpointsFavoriteListProvider extends AbstractFavoritesListProvid
private final List<BreakpointPanelProvider> myBreakpointPanelProviders;
private final BreakpointItemsTreeController myTreeController;
private final List<XBreakpointGroupingRule> myRulesAvailable = new ArrayList<XBreakpointGroupingRule>();
- private final BreakpointsSimpleTree myTree;
private Set<XBreakpointGroupingRule> myRulesEnabled = new TreeSet<XBreakpointGroupingRule>(new Comparator<XBreakpointGroupingRule>() {
@Override
@@ -66,8 +65,7 @@ public class BreakpointsFavoriteListProvider extends AbstractFavoritesListProvid
super(project, "Breakpoints");
myBreakpointPanelProviders = XBreakpointUtil.collectPanelProviders();
myTreeController = new BreakpointItemsTreeController(myRulesAvailable);
- myTree = new BreakpointsSimpleTree(myProject, myTreeController);
- myTreeController.setTreeView(myTree);
+ myTreeController.setTreeView(new BreakpointsSimpleTree(myProject, myTreeController));
updateChildren();
for (final BreakpointPanelProvider provider : myBreakpointPanelProviders) {
provider.addListener(this, myProject, myProject);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java
index aed4f88cf2a0..f7dff8b23760 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java
@@ -86,7 +86,10 @@ class XBreakpointItem extends BreakpointItem {
public void doUpdateDetailView(DetailView panel, boolean editorOnly) {
Project project = ((XBreakpointBase)myBreakpoint).getProject();
//saveState();
- myPropertiesPanel = null;
+ if (myPropertiesPanel != null) {
+ myPropertiesPanel.dispose();
+ myPropertiesPanel = null;
+ }
if (!editorOnly) {
myPropertiesPanel = new XLightBreakpointPropertiesPanel<XBreakpoint<?>>(project, getManager(), myBreakpoint, true);
@@ -178,4 +181,10 @@ class XBreakpointItem extends BreakpointItem {
return 0;
}
}
+
+ public void dispose() {
+ if (myPropertiesPanel != null) {
+ myPropertiesPanel.dispose();
+ }
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java
index eb183f9145e9..233c473fc952 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java
@@ -50,6 +50,7 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
public static final SkipDefaultValuesSerializationFilters SERIALIZATION_FILTER = new SkipDefaultValuesSerializationFilters();
private final MultiValuesMap<XBreakpointType, XBreakpointBase<?,?,?>> myBreakpoints = new MultiValuesMap<XBreakpointType, XBreakpointBase<?,?,?>>(true);
private final Map<XBreakpointType, XBreakpointBase<?,?,?>> myDefaultBreakpoints = new LinkedHashMap<XBreakpointType, XBreakpointBase<?, ?, ?>>();
+ private final Map<XBreakpointType, BreakpointState<?,?,?>> myBreakpointsDefaults = new LinkedHashMap<XBreakpointType, BreakpointState<?, ?, ?>>();
private final Set<XBreakpointBase<?,?,?>> myAllBreakpoints = new HashSet<XBreakpointBase<?, ?, ?>>();
private final Map<XBreakpointType, EventDispatcher<XBreakpointListener>> myDispatchers = new HashMap<XBreakpointType, EventDispatcher<XBreakpointListener>>();
private XBreakpointsDialogState myBreakpointsDialogSettings;
@@ -67,14 +68,16 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
myAllBreakpointsDispatcher = EventDispatcher.create(XBreakpointListener.class);
myDependentBreakpointManager = new XDependentBreakpointManager(this);
myLineBreakpointManager = new XLineBreakpointManager(project, myDependentBreakpointManager, startupManager);
- if (!project.isDefault() && !ApplicationManager.getApplication().isUnitTestMode()) {
- HttpVirtualFileListener httpVirtualFileListener = new HttpVirtualFileListener() {
- @Override
- public void fileDownloaded(@NotNull final VirtualFile file) {
- updateBreakpointInFile(file);
- }
- };
- HttpFileSystem.getInstance().addFileListener(httpVirtualFileListener, project);
+ if (!project.isDefault()) {
+ if (!ApplicationManager.getApplication().isUnitTestMode()) {
+ HttpVirtualFileListener httpVirtualFileListener = new HttpVirtualFileListener() {
+ @Override
+ public void fileDownloaded(@NotNull final VirtualFile file) {
+ updateBreakpointInFile(file);
+ }
+ };
+ HttpFileSystem.getInstance().addFileListener(httpVirtualFileListener, project);
+ }
for (XBreakpointType<?, ?> type : XBreakpointUtil.getBreakpointTypes()) {
addDefaultBreakpoint(type);
}
@@ -127,6 +130,7 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
BreakpointState<?,T,?> state = new BreakpointState<XBreakpoint<T>,T,XBreakpointType<XBreakpoint<T>,T>>(enabled,
type.getId(),
defaultBreakpoint ? 0 : myTime++);
+ getBreakpointDefaults(type).applyDefaults(state);
return new XBreakpointBase<XBreakpoint<T>,T, BreakpointState<?,T,?>>(type, this, properties, state);
}
@@ -213,8 +217,11 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
@Nullable final T properties,
boolean temporary) {
ApplicationManager.getApplication().assertWriteAccessAllowed();
+ LineBreakpointState<T> state = new LineBreakpointState<T>(true, type.getId(), fileUrl, line, temporary,
+ myTime++);
+ getBreakpointDefaults(type).applyDefaults(state);
XLineBreakpointImpl<T> breakpoint = new XLineBreakpointImpl<T>(type, this, properties,
- new LineBreakpointState<T>(true, type.getId(), fileUrl, line, temporary, myTime++));
+ state);
addBreakpoint(breakpoint, false, true);
return breakpoint;
}
@@ -353,6 +360,12 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
state.getBreakpoints().add(breakpoint.getState());
}
+ for (Map.Entry<XBreakpointType, BreakpointState<?,?,?>> entry : myBreakpointsDefaults.entrySet()) {
+ if (statesAreDifferent(entry.getValue(), createBreakpointDefaults(entry.getKey()))) {
+ state.getBreakpointsDefaults().add(entry.getValue());
+ }
+ }
+
state.setBreakpointsDialogProperties(myBreakpointsDialogSettings);
state.setTime(myTime);
return state;
@@ -366,9 +379,13 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
}
BreakpointState defaultState = ((XBreakpointBase)defaultBreakpoint).getState();
- Element defaultElement = XmlSerializer.serialize(defaultState, SERIALIZATION_FILTER);
- Element currentElement = XmlSerializer.serialize(state, SERIALIZATION_FILTER);
- return !JDOMUtil.areElementsEqual(defaultElement, currentElement);
+ return statesAreDifferent(state, defaultState);
+ }
+
+ private static boolean statesAreDifferent(BreakpointState state1, BreakpointState state2) {
+ Element elem1 = XmlSerializer.serialize(state1, SERIALIZATION_FILTER);
+ Element elem2 = XmlSerializer.serialize(state2, SERIALIZATION_FILTER);
+ return !JDOMUtil.areElementsEqual(elem1, elem2);
}
@Override
@@ -377,6 +394,8 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
myAllBreakpoints.clear();
myDefaultBreakpoints.clear();
+ myBreakpointsDefaults.clear();
+
for (BreakpointState breakpointState : state.getDefaultBreakpoints()) {
loadBreakpoint(breakpointState, true);
}
@@ -392,6 +411,12 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
for (BreakpointState breakpointState : state.getBreakpoints()) {
loadBreakpoint(breakpointState, false);
}
+
+ for (BreakpointState defaults : state.getBreakpointsDefaults()) {
+ XBreakpointType<?,?> type = XBreakpointUtil.findType(defaults.getTypeId());
+ myBreakpointsDefaults.put(type, defaults);
+ }
+
myDependentBreakpointManager.loadState();
myLineBreakpointManager.updateBreakpointsUI();
myTime = state.getTime();
@@ -439,11 +464,26 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
return breakpointState.createBreakpoint(type, this);
}
+ public BreakpointState getBreakpointDefaults(XBreakpointType type) {
+ BreakpointState defaultState = myBreakpointsDefaults.get(type);
+ if (defaultState == null) {
+ defaultState = createBreakpointDefaults(type);
+ myBreakpointsDefaults.put(type, defaultState);
+ }
+ return defaultState;
+ }
+
+ private static BreakpointState createBreakpointDefaults(XBreakpointType type) {
+ BreakpointState state = new BreakpointState();
+ state.setTypeId(type.getId());
+ return state;
+ }
@Tag("breakpoint-manager")
public static class BreakpointManagerState {
private List<BreakpointState> myDefaultBreakpoints = new ArrayList<BreakpointState>();
private List<BreakpointState> myBreakpoints = new ArrayList<BreakpointState>();
+ private List<BreakpointState> myBreakpointsDefaults = new ArrayList<BreakpointState>();
private XBreakpointsDialogState myBreakpointsDialogProperties;
private long myTime;
@@ -461,6 +501,13 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
return myBreakpoints;
}
+ @Tag("breakpoints-defaults")
+ @AbstractCollection(surroundWithTag = false,
+ elementTypes = {BreakpointState.class, LineBreakpointState.class})
+ public List<BreakpointState> getBreakpointsDefaults() {
+ return myBreakpointsDefaults;
+ }
+
@Tag("breakpoints-dialog")
public XBreakpointsDialogState getBreakpointsDialogProperties() {
return myBreakpointsDialogProperties;
@@ -475,6 +522,10 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
myDefaultBreakpoints = defaultBreakpoints;
}
+ public void setBreakpointsDefaults(List<BreakpointState> breakpointsDefaults) {
+ myBreakpointsDefaults = breakpointsDefaults;
+ }
+
public void setBreakpointsDialogProperties(XBreakpointsDialogState breakpointsDialogProperties) {
myBreakpointsDialogProperties = breakpointsDialogProperties;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
index 6aae02242ec4..07214a6f7671 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.MarkupModelEx;
+import com.intellij.openapi.editor.ex.RangeHighlighterEx;
import com.intellij.openapi.editor.impl.DocumentMarkupModel;
import com.intellij.openapi.editor.markup.GutterDraggableObject;
import com.intellij.openapi.editor.markup.RangeHighlighter;
@@ -54,7 +55,7 @@ import java.util.List;
* @author nik
*/
public class XLineBreakpointImpl<P extends XBreakpointProperties> extends XBreakpointBase<XLineBreakpoint<P>, P, LineBreakpointState<P>> implements XLineBreakpoint<P> {
- @Nullable private RangeHighlighter myHighlighter;
+ @Nullable private RangeHighlighterEx myHighlighter;
private final XLineBreakpointType<P> myType;
private XSourcePosition mySourcePosition;
private boolean myDisposed;
@@ -86,25 +87,37 @@ public class XLineBreakpointImpl<P extends XBreakpointProperties> extends XBreak
EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
TextAttributes attributes = scheme.getAttributes(DebuggerColors.BREAKPOINT_ATTRIBUTES);
- RangeHighlighter highlighter = myHighlighter;
- if (highlighter != null && highlighter.isValid() && document.getLineNumber(highlighter.getStartOffset()) != getLine()) {
+ RangeHighlighterEx highlighter = myHighlighter;
+ if (highlighter != null && (!highlighter.isValid() || document.getLineNumber(highlighter.getStartOffset()) != getLine())) {
highlighter.dispose();
myHighlighter = null;
highlighter = null;
}
+ MarkupModelEx markupModel;
if (highlighter == null) {
- MarkupModelEx markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, getProject(), true);
+ markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, getProject(), true);
highlighter = markupModel.addPersistentLineHighlighter(getLine(), DebuggerColors.BREAKPOINT_HIGHLIGHTER_LAYER, attributes);
- if (highlighter != null) {
- highlighter.setGutterIconRenderer(createGutterIconRenderer());
- highlighter.putUserData(DebuggerColors.BREAKPOINT_HIGHLIGHTER_KEY, Boolean.TRUE);
- myHighlighter = highlighter;
+ if (highlighter == null) {
+ return;
}
+
+ highlighter.setGutterIconRenderer(createGutterIconRenderer());
+ highlighter.putUserData(DebuggerColors.BREAKPOINT_HIGHLIGHTER_KEY, Boolean.TRUE);
+ myHighlighter = highlighter;
+ }
+ else {
+ markupModel = null;
}
- if (highlighter != null) {
- updateIcon();
+ updateIcon();
+
+ if (markupModel == null) {
+ markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, getProject(), false);
+ if (markupModel != null) {
+ // renderersChanged false — we don't change gutter size
+ markupModel.fireAttributesChanged(highlighter, false);
+ }
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java
index e438b857a6ba..67b0ece2f5ac 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java
@@ -167,7 +167,7 @@ public class BreakpointsDialog extends DialogWrapper {
@NotNull
@Override
protected Action[] createActions() {
- return new Action[]{getOKAction()};
+ return new Action[]{getOKAction(), getHelpAction()};
}
private class ToggleBreakpointGroupingRuleEnabledAction extends ToggleActionButton {
@@ -380,6 +380,12 @@ public class BreakpointsDialog extends DialogWrapper {
}
}
+ @Nullable
+ @Override
+ protected String getHelpId() {
+ return "reference.dialogs.breakpoints";
+ }
+
private void saveCurrentItem() {
ItemWrapper item = myDetailController.getSelectedItem();
if (item instanceof BreakpointItem) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultConditionComboBoxPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultConditionComboBoxPanel.java
new file mode 100644
index 000000000000..9cee406625a7
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultConditionComboBoxPanel.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.breakpoints.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.xdebugger.XSourcePosition;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import com.intellij.xdebugger.impl.ui.XDebuggerExpressionComboBox;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * @author egor
+ */
+public class DefaultConditionComboBoxPanel<B extends XBreakpoint<?>> extends XBreakpointCustomPropertiesPanel<B> {
+ private XDebuggerExpressionComboBox myConditionComboBox;
+
+ public DefaultConditionComboBoxPanel(Project project,
+ XDebuggerEditorsProvider debuggerEditorsProvider,
+ String historyId,
+ XSourcePosition sourcePosition) {
+ myConditionComboBox = new XDebuggerExpressionComboBox(project, debuggerEditorsProvider, historyId, sourcePosition);
+ }
+
+ @NotNull
+ @Override
+ public JComponent getComponent() {
+ return myConditionComboBox.getComponent();
+ }
+
+ @Override
+ public void saveTo(@NotNull B breakpoint) {
+ final String condition = StringUtil.nullize(myConditionComboBox.getText(), true);
+ breakpoint.setCondition(condition);
+ if (condition != null) {
+ myConditionComboBox.saveTextInHistory();
+ }
+ }
+
+ @Override
+ public void loadFrom(@NotNull B breakpoint) {
+ myConditionComboBox.setText(StringUtil.notNullize(breakpoint.getCondition()));
+ }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultLogExpressionComboBoxPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultLogExpressionComboBoxPanel.java
new file mode 100644
index 000000000000..a4ff954c7375
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultLogExpressionComboBoxPanel.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.breakpoints.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.xdebugger.XSourcePosition;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import com.intellij.xdebugger.impl.ui.XDebuggerExpressionComboBox;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * @author egor
+ */
+public class DefaultLogExpressionComboBoxPanel<B extends XBreakpoint<?>> extends XBreakpointCustomPropertiesPanel<B> {
+ private XDebuggerExpressionComboBox myLogExpressionComboBox;
+
+ public DefaultLogExpressionComboBoxPanel(Project project,
+ XDebuggerEditorsProvider debuggerEditorsProvider,
+ String historyId,
+ XSourcePosition sourcePosition) {
+ myLogExpressionComboBox = new XDebuggerExpressionComboBox(project, debuggerEditorsProvider, historyId, sourcePosition);
+ }
+
+ @NotNull
+ @Override
+ public JComponent getComponent() {
+ return myLogExpressionComboBox.getComponent();
+ }
+
+ @Override
+ public void saveTo(@NotNull B breakpoint) {
+ String logExpression = myLogExpressionComboBox.getComponent().isEnabled() ? myLogExpressionComboBox.getText() : null;
+ breakpoint.setLogExpression(logExpression);
+ myLogExpressionComboBox.saveTextInHistory();
+ }
+
+ @Override
+ public void loadFrom(@NotNull B breakpoint) {
+ String logExpression = breakpoint.getLogExpression();
+ myLogExpressionComboBox.setText(logExpression != null ? logExpression : "");
+ }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
index 26049ac69e51..2ccff41e5c7e 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
@@ -19,9 +19,9 @@ import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XBreakpointManager;
import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
-import com.intellij.xdebugger.impl.ui.XDebuggerExpressionComboBox;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -44,7 +44,7 @@ public class XBreakpointActionsPanel<B extends XBreakpoint<?>> extends XBreakpoi
private JPanel myContentPane;
private JPanel myMainPanel;
private JCheckBox myTemporaryCheckBox;
- private XDebuggerExpressionComboBox myLogExpressionComboBox;
+ XBreakpointCustomPropertiesPanel<B> logExpressionPanel;
public void init(Project project, XBreakpointManager breakpointManager, @NotNull B breakpoint, @Nullable XDebuggerEditorsProvider debuggerEditorsProvider) {
init(project, breakpointManager, breakpoint);
@@ -55,10 +55,18 @@ public class XBreakpointActionsPanel<B extends XBreakpoint<?>> extends XBreakpoi
}
};
- myLogExpressionComboBox = new XDebuggerExpressionComboBox(project, debuggerEditorsProvider, "breakpointLogExpression", myBreakpoint.getSourcePosition());
- JComponent logExpressionComponent = myLogExpressionComboBox.getComponent();
+ if (debuggerEditorsProvider instanceof XDebuggerComboBoxProvider) {
+ logExpressionPanel = ((XDebuggerComboBoxProvider<B>)debuggerEditorsProvider).createLogExpressionComboBoxPanel(
+ project, debuggerEditorsProvider, "breakpointCondition", myBreakpoint.getSourcePosition());
+ }
+ else {
+ logExpressionPanel =
+ new DefaultLogExpressionComboBoxPanel<B>(project, debuggerEditorsProvider, "breakpointCondition", myBreakpoint.getSourcePosition());
+ }
+
+ JComponent logExpressionComponent = logExpressionPanel.getComponent();
myLogExpressionPanel.add(logExpressionComponent, BorderLayout.CENTER);
- myLogExpressionComboBox.setEnabled(false);
+ logExpressionComponent.setEnabled(false);
myTemporaryCheckBox.setVisible(breakpoint instanceof XLineBreakpoint);
myLogExpressionCheckBox.addActionListener(listener);
DebuggerUIUtil.focusEditorOnCheck(myLogExpressionCheckBox, logExpressionComponent);
@@ -81,8 +89,8 @@ public class XBreakpointActionsPanel<B extends XBreakpoint<?>> extends XBreakpoi
}
private void onCheckboxChanged() {
- if (myLogExpressionComboBox != null) {
- myLogExpressionComboBox.setEnabled(myLogExpressionCheckBox.isSelected());
+ if (logExpressionPanel != null) {
+ logExpressionPanel.getComponent().setEnabled(myLogExpressionCheckBox.isSelected());
}
}
@@ -94,10 +102,9 @@ public class XBreakpointActionsPanel<B extends XBreakpoint<?>> extends XBreakpoi
myTemporaryCheckBox.setSelected(((XLineBreakpoint)myBreakpoint).isTemporary());
}
- if (myLogExpressionComboBox != null) {
- String logExpression = myBreakpoint.getLogExpression();
- myLogExpressionCheckBox.setSelected(logExpression != null);
- myLogExpressionComboBox.setText(logExpression != null ? logExpression : "");
+ if (logExpressionPanel != null) {
+ myLogExpressionCheckBox.setSelected(myBreakpoint.getLogExpression() != null);
+ logExpressionPanel.loadFrom(myBreakpoint);
}
onCheckboxChanged();
}
@@ -110,11 +117,14 @@ public class XBreakpointActionsPanel<B extends XBreakpoint<?>> extends XBreakpoi
((XLineBreakpoint)myBreakpoint).setTemporary(myTemporaryCheckBox.isSelected());
}
- if (myLogExpressionComboBox != null) {
- String logExpression = myLogExpressionCheckBox.isSelected() ? myLogExpressionComboBox.getText() : null;
- myBreakpoint.setLogExpression(logExpression);
- myLogExpressionComboBox.saveTextInHistory();
+ if (logExpressionPanel != null) {
+ logExpressionPanel.saveTo(myBreakpoint);
}
+ }
+ public void dispose() {
+ if (logExpressionPanel != null) {
+ logExpressionPanel.dispose();
+ }
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XDebuggerComboBoxProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XDebuggerComboBoxProvider.java
new file mode 100644
index 000000000000..fd5391146657
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XDebuggerComboBoxProvider.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 com.intellij.xdebugger.impl.breakpoints.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.xdebugger.XSourcePosition;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+
+/**
+ * @author egor
+ */
+public interface XDebuggerComboBoxProvider<B extends XBreakpoint<?>> {
+ XBreakpointCustomPropertiesPanel<B> createConditionComboBoxPanel(Project project,
+ XDebuggerEditorsProvider debuggerEditorsProvider,
+ String historyId,
+ XSourcePosition sourcePosition);
+
+ XBreakpointCustomPropertiesPanel<B> createLogExpressionComboBoxPanel(Project project,
+ XDebuggerEditorsProvider debuggerEditorsProvider,
+ String historyId,
+ XSourcePosition sourcePosition);
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
index bc6d5e4395ae..7c910835dd63 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
@@ -16,7 +16,6 @@
package com.intellij.xdebugger.impl.breakpoints.ui;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.popup.util.DetailView;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
@@ -26,7 +25,6 @@ import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase;
import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil;
-import com.intellij.xdebugger.impl.ui.XDebuggerExpressionComboBox;
import javax.swing.*;
import java.awt.*;
@@ -83,8 +81,6 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
private List<XBreakpointPropertiesSubPanel<B>> mySubPanels = new ArrayList<XBreakpointPropertiesSubPanel<B>>();
- private XDebuggerExpressionComboBox myConditionComboBox;
-
private B myBreakpoint;
public void setDetailView(DetailView detailView) {
@@ -106,10 +102,25 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
myActionsPanel.init(project, breakpointManager, breakpoint, debuggerEditorsProvider);
mySubPanels.add(myActionsPanel);
+ myCustomPanels = new ArrayList<XBreakpointCustomPropertiesPanel<B>>();
if (debuggerEditorsProvider != null) {
- myConditionComboBox = new XDebuggerExpressionComboBox(project, debuggerEditorsProvider, "breakpointCondition", myBreakpoint.getSourcePosition());
- JComponent conditionComponent = myConditionComboBox.getComponent();
- myConditionExpressionPanel.add(conditionComponent, BorderLayout.CENTER);
+ final XBreakpointCustomPropertiesPanel<B> conditionPanel;
+ if (debuggerEditorsProvider instanceof XDebuggerComboBoxProvider) {
+ conditionPanel = ((XDebuggerComboBoxProvider<B>)debuggerEditorsProvider).createConditionComboBoxPanel(
+ project, debuggerEditorsProvider, "breakpointCondition", myBreakpoint.getSourcePosition());
+ }
+ else {
+ conditionPanel =
+ new DefaultConditionComboBoxPanel<B>(project, debuggerEditorsProvider, "breakpointCondition", myBreakpoint.getSourcePosition());
+ }
+ myConditionExpressionPanel.add(conditionPanel.getComponent(), BorderLayout.CENTER);
+ myCustomPanels.add(conditionPanel);
+ myMainPanel.addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusGained(FocusEvent event) {
+ IdeFocusManager.findInstance().requestFocus(conditionPanel.getComponent(), false);
+ }
+ });
} else {
myConditionPanel.setVisible(false);
}
@@ -121,7 +132,6 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
}
}
- myCustomPanels = new ArrayList<XBreakpointCustomPropertiesPanel<B>>();
XBreakpointCustomPropertiesPanel<B> customPropertiesPanel = breakpointType.createCustomPropertiesPanel();
if (customPropertiesPanel != null) {
myCustomPropertiesPanelWrapper.add(customPropertiesPanel.getComponent(), BorderLayout.CENTER);
@@ -140,14 +150,6 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
myCustomPanels.add(customRightConditionPanel);
}
- myMainPanel.addFocusListener(new FocusAdapter() {
- @Override
- public void focusGained(FocusEvent event) {
- if (myConditionComboBox != null) {
- IdeFocusManager.findInstance().requestFocus(myConditionComboBox.getComponent(), false);
- }
- }
- });
myEnabledCheckbox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
@@ -161,14 +163,6 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
panel.saveProperties();
}
- if (myConditionComboBox != null) {
- final String condition = StringUtil.nullize(myConditionComboBox.getText(), true);
- myBreakpoint.setCondition(condition);
- if (condition != null) {
- myConditionComboBox.saveTextInHistory();
- }
- }
-
for (XBreakpointCustomPropertiesPanel<B> customPanel : myCustomPanels) {
customPanel.saveTo(myBreakpoint);
}
@@ -183,10 +177,6 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
panel.loadProperties();
}
- if (myConditionComboBox != null) {
- myConditionComboBox.setText(StringUtil.notNullize(myBreakpoint.getCondition()));
- }
-
for (XBreakpointCustomPropertiesPanel<B> customPanel : myCustomPanels) {
customPanel.loadFrom(myBreakpoint);
}
@@ -197,4 +187,11 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
public JPanel getMainPanel() {
return myMainPanel;
}
+
+ public void dispose() {
+ myActionsPanel.dispose();
+ for (XBreakpointCustomPropertiesPanel<B> panel : myCustomPanels) {
+ panel.dispose();
+ }
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java
index c46914fa06b8..b3dcd1302735 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java
@@ -15,11 +15,11 @@
*/
package com.intellij.xdebugger.impl.breakpoints.ui;
-import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.breakpoints.SuspendPolicy;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XBreakpointManager;
+import com.intellij.xdebugger.impl.breakpoints.XBreakpointManagerImpl;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -72,7 +72,7 @@ public class XSuspendPolicyPanel<B extends XBreakpoint<?>> extends XBreakpointPr
mySuspendPolicyGroup.add(mySuspendAll);
mySuspendPolicyGroup.add(mySuspendThread);
- updateSuspendPolicyFont(createSettingsKey());
+ updateSuspendPolicyFont();
ItemListener suspendPolicyChangeListener = new ItemListener() {
@Override
@@ -89,9 +89,8 @@ public class XSuspendPolicyPanel<B extends XBreakpoint<?>> extends XBreakpointPr
@Override
public void actionPerformed(ActionEvent e) {
SuspendPolicy suspendPolicy = getSelectedSuspendPolicy();
- String settingsKey = createSettingsKey();
- PropertiesComponent.getInstance().setValue(settingsKey, suspendPolicy.name());
- updateSuspendPolicyFont(settingsKey);
+ ((XBreakpointManagerImpl)myBreakpointManager).getBreakpointDefaults(myBreakpointType).setSuspendPolicy(suspendPolicy);
+ updateSuspendPolicyFont();
if (SuspendPolicy.THREAD == suspendPolicy) {
mySuspendThread.requestFocus();
}
@@ -104,20 +103,16 @@ public class XSuspendPolicyPanel<B extends XBreakpoint<?>> extends XBreakpointPr
}
private void updateMakeDefaultEnableState() {
- myMakeDefaultButton.setEnabled(!getSelectedSuspendPolicy().name().equalsIgnoreCase(PropertiesComponent.getInstance().getValue(createSettingsKey(), SuspendPolicy.ALL.name())));
+ myMakeDefaultButton.setEnabled(!getSelectedSuspendPolicy().equals(((XBreakpointManagerImpl)myBreakpointManager).getBreakpointDefaults(myBreakpointType).getSuspendPolicy()));
}
- private String createSettingsKey() {
- return "debugger.suspend.policy-" + myBreakpointType.getId();
- }
-
- private void updateSuspendPolicyFont(String settingsKey) {
- String defaultPolicy = PropertiesComponent.getInstance().getValue(settingsKey, SuspendPolicy.ALL.name());
+ private void updateSuspendPolicyFont() {
+ SuspendPolicy defaultPolicy = ((XBreakpointManagerImpl)myBreakpointManager).getBreakpointDefaults(myBreakpointType).getSuspendPolicy();
Font font = mySuspendAll.getFont().deriveFont(Font.PLAIN);
Font boldFont = font.deriveFont(Font.BOLD);
- mySuspendAll.setFont(SuspendPolicy.ALL.name().equalsIgnoreCase(defaultPolicy) ? boldFont : font);
- mySuspendThread.setFont(SuspendPolicy.THREAD.name().equalsIgnoreCase(defaultPolicy) ? boldFont : font);
+ mySuspendAll.setFont(SuspendPolicy.ALL.equals(defaultPolicy) ? boldFont : font);
+ mySuspendThread.setFont(SuspendPolicy.THREAD.equals(defaultPolicy) ? boldFont : font);
}
private void changeEnableState(boolean selected) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointTypeGroup.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointTypeGroup.java
index d00e27418edc..c0005393a8a4 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointTypeGroup.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointTypeGroup.java
@@ -17,6 +17,8 @@ package com.intellij.xdebugger.impl.breakpoints.ui.grouping;
import com.intellij.util.ArrayUtil;
import com.intellij.xdebugger.breakpoints.XBreakpointType;
+import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
+import com.intellij.xdebugger.breakpoints.XLineBreakpointType;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup;
import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil;
import org.jetbrains.annotations.NotNull;
@@ -49,6 +51,22 @@ public class XBreakpointTypeGroup extends XBreakpointGroup {
@Override
public int compareTo(XBreakpointGroup o) {
if (o instanceof XBreakpointTypeGroup) {
+ if (((XBreakpointTypeGroup)o).myBreakpointType instanceof XLineBreakpointType) {
+ if (myBreakpointType instanceof XLineBreakpointType) {
+ int res = ((XLineBreakpointType)((XBreakpointTypeGroup)o).myBreakpointType).getPriority() -
+ ((XLineBreakpointType)myBreakpointType).getPriority();
+ if (res != 0) {
+ return res;
+ }
+ }
+ else {
+ // line breakpoints should be on top
+ return 1;
+ }
+ }
+ else if (myBreakpointType instanceof XLineBreakpointType) {
+ return -1;
+ }
return indexOfType(myBreakpointType) - indexOfType(((XBreakpointTypeGroup)o).getBreakpointType());
}
return -o.compareTo(this);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java
index babdd0939ace..7c90280fc0f3 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java
@@ -43,7 +43,6 @@ public class BreakpointItemsTreeController implements BreakpointsCheckboxTree.De
private final CheckedTreeNode myRoot;
private final Map<BreakpointItem, BreakpointItemNode> myNodes = new HashMap<BreakpointItem, BreakpointItemNode>();
private List<XBreakpointGroupingRule> myGroupingRules;
- private final Map<XBreakpointGroup, BreakpointsGroupNode> myGroupNodes = new HashMap<XBreakpointGroup, BreakpointsGroupNode>();
private final MultiValuesMap<XBreakpointGroupingRule, XBreakpointGroup> myGroups = new MultiValuesMap<XBreakpointGroupingRule, XBreakpointGroup>();
@@ -110,7 +109,6 @@ public class BreakpointItemsTreeController implements BreakpointsCheckboxTree.De
final TreeState state = TreeState.createOn(myTreeView, myRoot);
myRoot.removeAllChildren();
myNodes.clear();
- myGroupNodes.clear();
myGroups.clear();
for (BreakpointItem breakpoint : breakpoints) {
BreakpointItemNode node = new BreakpointItemNode(breakpoint);
@@ -130,53 +128,42 @@ public class BreakpointItemsTreeController implements BreakpointsCheckboxTree.De
@NotNull
private CheckedTreeNode getParentNode(final BreakpointItem breakpoint) {
CheckedTreeNode parent = myRoot;
- XBreakpointGroup parentGroup = null;
for (int i = 0; i < myGroupingRules.size(); i++) {
- XBreakpointGroup group = getGroup(parentGroup, breakpoint, myGroupingRules.get(i));
+ Collection<XBreakpointGroup> existingGroups = getGroupNodes(parent);
+ XBreakpointGroup group = myGroupingRules.get(i).getGroup(breakpoint.getBreakpoint(), existingGroups);
if (group != null) {
parent = getOrCreateGroupNode(parent, group, i);
- parentGroup = group;
}
}
return parent;
}
- @Nullable
- private XBreakpointGroup getGroup(XBreakpointGroup parentGroup, final BreakpointItem breakpoint, final XBreakpointGroupingRule groupingRule) {
- //noinspection unchecked
- Collection<XBreakpointGroup> groups = myGroups.get(groupingRule);
- if (groups == null) {
- groups = Collections.emptyList();
- }
-
- XBreakpointGroup group = groupingRule.getGroup(breakpoint.getBreakpoint(), filterByParent(parentGroup, groups));
- if (group != null) {
- myGroups.put(groupingRule, group);
- }
- return group;
- }
-
- private Collection<XBreakpointGroup> filterByParent(XBreakpointGroup parentGroup, Collection<XBreakpointGroup> groups) {
- Collection<XBreakpointGroup> filtered = new ArrayList<XBreakpointGroup>();
- for (XBreakpointGroup group : groups) {
- TreeNode parentNode = myGroupNodes.get(group).getParent();
- BreakpointsGroupNode parent = parentNode instanceof BreakpointsGroupNode ? (BreakpointsGroupNode)parentNode : null;
- if ((parentGroup == null && parentNode == myRoot) || (parent != null && parent.getGroup() == parentGroup)) {
- filtered.add(group);
+ private static Collection<XBreakpointGroup> getGroupNodes(CheckedTreeNode parent) {
+ Collection<XBreakpointGroup> nodes = new ArrayList<XBreakpointGroup>();
+ Enumeration children = parent.children();
+ while (children.hasMoreElements()) {
+ Object element = children.nextElement();
+ if (element instanceof BreakpointsGroupNode) {
+ nodes.add(((BreakpointsGroupNode)element).getGroup());
}
}
- return filtered;
+ return nodes;
}
- private <G extends XBreakpointGroup> BreakpointsGroupNode<G> getOrCreateGroupNode(CheckedTreeNode parent, final G group,
+ private static BreakpointsGroupNode getOrCreateGroupNode(CheckedTreeNode parent, final XBreakpointGroup group,
final int level) {
- //noinspection unchecked
- BreakpointsGroupNode<G> groupNode = (BreakpointsGroupNode<G>)myGroupNodes.get(group);
- if (groupNode == null) {
- groupNode = new BreakpointsGroupNode<G>(group, level);
- myGroupNodes.put(group, groupNode);
- parent.add(groupNode);
+ Enumeration children = parent.children();
+ while (children.hasMoreElements()) {
+ Object element = children.nextElement();
+ if (element instanceof BreakpointsGroupNode) {
+ XBreakpointGroup groupFound = ((BreakpointsGroupNode)element).getGroup();
+ if (groupFound.equals(group)) {
+ return (BreakpointsGroupNode)element;
+ }
+ }
}
+ BreakpointsGroupNode groupNode = new BreakpointsGroupNode<XBreakpointGroup>(group, level);
+ parent.add(groupNode);
return groupNode;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
index 741b2878e8b2..4abf17312585 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
@@ -29,7 +29,6 @@ import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.EvaluationMode;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
-import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase;
@@ -38,6 +37,7 @@ import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
import com.intellij.xdebugger.impl.ui.tree.nodes.EvaluatingExpressionRootNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -61,10 +61,10 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
private final boolean myIsCodeFragmentEvaluationSupported;
public XDebuggerEvaluationDialog(@NotNull XDebugSession session,
- final @NotNull XDebuggerEditorsProvider editorsProvider,
+ @NotNull XDebuggerEditorsProvider editorsProvider,
@NotNull XDebuggerEvaluator evaluator,
@NotNull String text,
- final XSourcePosition sourcePosition) {
+ @Nullable XSourcePosition sourcePosition) {
super(session.getProject(), true);
mySession = session;
myEditorsProvider = editorsProvider;
@@ -212,8 +212,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
inputEditor.saveTextInHistory();
String expression = inputEditor.getText();
- XStackFrame frame = mySession.getCurrentStackFrame();
- XDebuggerEvaluator evaluator = frame == null ? null : frame.getEvaluator();
+ XDebuggerEvaluator evaluator = mySession.getDebugProcess().getEvaluator();
if (evaluator == null) {
evaluationCallback.errorOccurred(XDebuggerBundle.message("xdebugger.evaluate.stack.frame.has.not.evaluator"));
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java
index 8813e70d823b..81e94ff7a851 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java
@@ -26,7 +26,6 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
-import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.impl.evaluate.quick.common.AbstractValueHint;
import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType;
@@ -44,11 +43,7 @@ public class XQuickEvaluateHandler extends QuickEvaluateHandler {
@Override
public boolean isEnabled(@NotNull final Project project) {
XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
- if (session == null || !session.isSuspended()) {
- return false;
- }
- XStackFrame stackFrame = session.getCurrentStackFrame();
- return stackFrame != null && stackFrame.getEvaluator() != null;
+ return session != null && session.getDebugProcess().getEvaluator() != null;
}
@Override
@@ -58,11 +53,7 @@ public class XQuickEvaluateHandler extends QuickEvaluateHandler {
return null;
}
- XStackFrame stackFrame = session.getCurrentStackFrame();
- if (stackFrame == null) {
- return null;
- }
- final XDebuggerEvaluator evaluator = stackFrame.getEvaluator();
+ final XDebuggerEvaluator evaluator = session.getDebugProcess().getEvaluator();
if (evaluator == null) {
return null;
}
@@ -111,12 +102,9 @@ public class XQuickEvaluateHandler extends QuickEvaluateHandler {
public int getValueLookupDelay(final Project project) {
XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
if (session != null) {
- XStackFrame stackFrame = session.getCurrentStackFrame();
- if (stackFrame != null) {
- XDebuggerEvaluator evaluator = stackFrame.getEvaluator();
- if (evaluator != null) {
- return evaluator.getValuePopupDelay();
- }
+ XDebuggerEvaluator evaluator = session.getDebugProcess().getEvaluator();
+ if (evaluator != null) {
+ return evaluator.getValuePopupDelay();
}
}
return 700;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java
index 415742b6a700..ebf5d69a166e 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java
@@ -16,6 +16,10 @@
package com.intellij.xdebugger.impl.evaluate.quick;
import com.intellij.codeInsight.hint.HintUtil;
+import com.intellij.execution.console.LanguageConsoleImpl;
+import com.intellij.execution.console.LanguageConsoleView;
+import com.intellij.execution.impl.ConsoleViewImpl;
+import com.intellij.execution.ui.ConsoleView;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -72,7 +76,17 @@ public class XValueHint extends AbstractValueHint {
myEvaluator = evaluator;
myDebugSession = session;
myExpression = XDebuggerEvaluateActionHandler.getExpressionText(expressionData, editor.getDocument());
- final VirtualFile file = FileDocumentManager.getInstance().getFile(editor.getDocument());
+
+ VirtualFile file;
+ ConsoleView consoleView = ConsoleViewImpl.CONSOLE_VIEW_IN_EDITOR_VIEW.get(editor);
+ if (consoleView instanceof LanguageConsoleView) {
+ LanguageConsoleImpl console = ((LanguageConsoleView)consoleView).getConsole();
+ file = console.getHistoryViewer() == editor ? console.getVirtualFile() : null;
+ }
+ else {
+ file = FileDocumentManager.getInstance().getFile(editor.getDocument());
+ }
+
myExpressionPosition = file != null ? XDebuggerUtil.getInstance().createPositionByOffset(file, expressionData.first.getStartOffset()) : null;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/ValueLookupManager.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/ValueLookupManager.java
index cd1cfe2b51a1..13facc097e93 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/ValueLookupManager.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/ValueLookupManager.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.editor.event.EditorMouseMotionListener;
import com.intellij.openapi.project.Project;
import com.intellij.util.Alarm;
import com.intellij.xdebugger.impl.DebuggerSupport;
+import org.jetbrains.annotations.NotNull;
import java.awt.*;
@@ -107,7 +108,7 @@ public class ValueLookupManager implements EditorMouseMotionListener {
}
}
- public void showHint(final QuickEvaluateHandler handler, Editor editor, Point point, ValueHintType type) {
+ public void showHint(@NotNull QuickEvaluateHandler handler, @NotNull Editor editor, @NotNull Point point, @NotNull ValueHintType type) {
myAlarm.cancelAllRequests();
if (editor.isDisposed() || !handler.canShowHint(myProject)) {
return;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
index 48defd3a08e9..088b4004798b 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
@@ -123,8 +123,7 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi
@Override
public void addWatchExpression(@NotNull String expression, int index, final boolean navigateToWatchNode) {
- XStackFrame stackFrame = mySession.getCurrentStackFrame();
- myRootNode.addWatchExpression(stackFrame == null ? null : stackFrame.getEvaluator(), expression, index, navigateToWatchNode);
+ myRootNode.addWatchExpression(mySession.getDebugProcess().getEvaluator(), expression, index, navigateToWatchNode);
updateSessionData();
}
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 abce43b858ec..d09bc7f37b65 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
@@ -141,6 +141,7 @@ public class DebuggerUIUtil {
final Ref<Balloon> balloonRef = Ref.create(null);
final Ref<Boolean> isLoading = Ref.create(Boolean.FALSE);
+ final Ref<Boolean> moreOptionsRequested = Ref.create(Boolean.FALSE);
propertiesPanel.setDelegate(new XLightBreakpointPropertiesPanel.Delegate() {
@Override
@@ -152,6 +153,7 @@ public class DebuggerUIUtil {
balloonRef.get().hide();
}
showXBreakpointEditorBalloon(project, point, component, true, breakpoint);
+ moreOptionsRequested.set(true);
}
});
@@ -159,10 +161,15 @@ public class DebuggerUIUtil {
propertiesPanel.loadProperties();
isLoading.set(Boolean.FALSE);
+ if (moreOptionsRequested.get()) {
+ return;
+ }
+
Runnable showMoreOptions = new Runnable() {
@Override
public void run() {
propertiesPanel.saveProperties();
+ propertiesPanel.dispose();
BreakpointsDialogFactory.getInstance(project).showDialog(breakpoint);
}
};
@@ -184,6 +191,7 @@ public class DebuggerUIUtil {
@Override
public void onClosed(LightweightWindowEvent event) {
propertiesPanel.saveProperties();
+ propertiesPanel.dispose();
breakpointManager.removeBreakpointListener(breakpointListener);
}
});
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 47485e568a14..db7aef7d61cb 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
@@ -72,7 +72,7 @@ public class ExecutionPointHighlighter {
public void navigateTo() {
if (myOpenFileDescriptor != null) {
- FileEditorManager.getInstance(myProject).openTextEditor(myOpenFileDescriptor, false);
+ FileEditorManager.getInstance(myProject).openTextEditor(myOpenFileDescriptor, true);
}
}
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 e442654c560a..1aa9e2cb53fb 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
@@ -144,6 +144,9 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
if (XWatchesView.DATA_KEY.is(dataId)) {
return myWatchesView;
}
+ if (LangDataKeys.CONSOLE_VIEW.is(dataId)) {
+ return session.getConsoleView();
+ }
return null;
}
});
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/EvaluateInConsoleFromTreeAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/EvaluateInConsoleFromTreeAction.java
new file mode 100644
index 000000000000..5bff527452c4
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/EvaluateInConsoleFromTreeAction.java
@@ -0,0 +1,32 @@
+package com.intellij.xdebugger.impl.ui.tree.actions;
+
+import com.intellij.execution.console.ConsoleExecuteAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.xdebugger.impl.actions.handlers.XEvaluateInConsoleFromEditorActionHandler;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+class EvaluateInConsoleFromTreeAction extends XAddToWatchesAction {
+ @Override
+ protected boolean isEnabled(@NotNull XValueNodeImpl node, @NotNull AnActionEvent e) {
+ return super.isEnabled(node, e) && getConsoleExecuteAction(e) != null;
+ }
+
+ @Nullable
+ private static ConsoleExecuteAction getConsoleExecuteAction(@NotNull AnActionEvent e) {
+ return XEvaluateInConsoleFromEditorActionHandler.getConsoleExecuteAction(e.getData(LangDataKeys.CONSOLE_VIEW));
+ }
+
+ @Override
+ protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) {
+ ConsoleExecuteAction action = getConsoleExecuteAction(e);
+ if (action != null) {
+ String expression = node.getValueContainer().getEvaluationExpression();
+ if (expression != null) {
+ action.execute(null, expression, null);
+ }
+ }
+ }
+} \ No newline at end of file
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 a3621cb1a621..eb6c1586f103 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
@@ -21,9 +21,9 @@ import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
/**
- * @author nik
+ * This action works only in the variables view, it is not generic action like {@see com.intellij.xdebugger.impl.actions.AddToWatchesAction}
*/
-public class XAddToWatchesAction extends XDebuggerTreeActionBase {
+class XAddToWatchesAction extends XDebuggerTreeActionBase {
@Override
protected boolean isEnabled(@NotNull final XValueNodeImpl node, @NotNull AnActionEvent e) {
return super.isEnabled(node, e) && node.getValueContainer().getEvaluationExpression() != null && e.getData(XWatchesView.DATA_KEY) != null;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/EvaluatingExpressionRootNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/EvaluatingExpressionRootNode.java
index 379b07c5426a..1833ae34d1e5 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/EvaluatingExpressionRootNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/EvaluatingExpressionRootNode.java
@@ -44,7 +44,7 @@ public class EvaluatingExpressionRootNode extends XValueContainerNode<Evaluating
public static class EvaluatingResultContainer extends XValueContainer implements XDebuggerTreeListener {
private final XDebuggerEvaluationDialog myDialog;
- private XDebuggerTree myTree;
+ private final XDebuggerTree myTree;
public EvaluatingResultContainer(final XDebuggerEvaluationDialog dialog, XDebuggerTree tree) {
myDialog = dialog;
diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointManagerTest.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointManagerTest.java
index 38e9154d936e..a4cd467e1627 100644
--- a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointManagerTest.java
+++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointManagerTest.java
@@ -32,23 +32,26 @@ import java.util.List;
public class XBreakpointManagerTest extends XBreakpointsTestCase {
public void testAddRemove() {
+ XBreakpoint<MyBreakpointProperties> defaultBreakpoint = myBreakpointManager.getDefaultBreakpoint(MY_SIMPLE_BREAKPOINT_TYPE);
+ assertSameElements(getAllBreakpoints(), defaultBreakpoint);
+
XLineBreakpoint<MyBreakpointProperties> lineBreakpoint =
myBreakpointManager.addLineBreakpoint(MY_LINE_BREAKPOINT_TYPE, "url", 239, new MyBreakpointProperties("123"));
XBreakpoint<MyBreakpointProperties> breakpoint = myBreakpointManager.addBreakpoint(MY_SIMPLE_BREAKPOINT_TYPE, new MyBreakpointProperties("abc"));
- assertSameElements(getAllBreakpoints(), breakpoint, lineBreakpoint);
+ assertSameElements(getAllBreakpoints(), breakpoint, lineBreakpoint, defaultBreakpoint);
assertSame(lineBreakpoint, assertOneElement(myBreakpointManager.getBreakpoints(MY_LINE_BREAKPOINT_TYPE)));
- assertSame(breakpoint, getSingleBreakpoint());
+ assertSameElements(myBreakpointManager.getBreakpoints(MY_SIMPLE_BREAKPOINT_TYPE), breakpoint, defaultBreakpoint);
myBreakpointManager.removeBreakpoint(lineBreakpoint);
- assertSame(breakpoint, assertOneElement(getAllBreakpoints()));
+ assertSameElements(getAllBreakpoints(), breakpoint, defaultBreakpoint);
assertTrue(myBreakpointManager.getBreakpoints(MY_LINE_BREAKPOINT_TYPE).isEmpty());
- assertSame(breakpoint, getSingleBreakpoint());
+ assertSameElements(myBreakpointManager.getBreakpoints(MY_SIMPLE_BREAKPOINT_TYPE), breakpoint, defaultBreakpoint);
myBreakpointManager.removeBreakpoint(breakpoint);
- assertEmpty(getAllBreakpoints());
- assertTrue(myBreakpointManager.getBreakpoints(MY_SIMPLE_BREAKPOINT_TYPE).isEmpty());
+ assertSameElements(getAllBreakpoints(), defaultBreakpoint);
+ assertSameElements(myBreakpointManager.getBreakpoints(MY_SIMPLE_BREAKPOINT_TYPE), defaultBreakpoint);
}
public void testSerialize() {
diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestUtil.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestUtil.java
index 3e4067f19ca9..0f140e38f893 100644
--- a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestUtil.java
+++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestUtil.java
@@ -65,7 +65,8 @@ public class XDebuggerTestUtil {
XBreakpointManager manager = XDebuggerManager.getInstance(project).getBreakpointManager();
XLineBreakpointImpl breakpoint = (XLineBreakpointImpl)manager.findBreakpointAtLine(type, file, line);
Assert.assertNotNull(breakpoint);
- Assert.assertEquals(validity ? AllIcons.Debugger.Db_verified_breakpoint : AllIcons.Debugger.Db_invalid_breakpoint, breakpoint.getIcon());
+ Assert
+ .assertEquals(validity ? AllIcons.Debugger.Db_verified_breakpoint : AllIcons.Debugger.Db_invalid_breakpoint, breakpoint.getIcon());
Assert.assertEquals(errorMessage, breakpoint.getErrorMessage());
}
@@ -303,7 +304,8 @@ public class XDebuggerTestUtil {
expectedNames.removeAll(actualNames);
UsefulTestCase.assertTrue("Missing variables:" + StringUtil.join(expectedNames, ", ")
+ "\nAll Variables: " + StringUtil.join(actualNames, ", "),
- expectedNames.isEmpty());
+ expectedNames.isEmpty()
+ );
}
public static void assertSourcePosition(final XValue value, VirtualFile file, int offset) {
@@ -366,8 +368,23 @@ public class XDebuggerTestUtil {
public static void removeAllBreakpoints(@NotNull final Project project) {
final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
XBreakpoint<?>[] breakpoints = breakpointManager.getAllBreakpoints();
- for (XBreakpoint b : breakpoints) {
- breakpointManager.removeBreakpoint(b);
+ for (final XBreakpoint b : breakpoints) {
+ new WriteAction() {
+ @Override
+ protected void run(Result result) throws Throwable {
+ breakpointManager.removeBreakpoint(b);
+ }
+ }.execute();
+ }
+ }
+
+ 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();
+ XBreakpointType<B, ?> bpType = XDebuggerUtil.getInstance().findBreakpointType(bpTypeClass);
+ XBreakpoint<?> bp = breakpointManager.getDefaultBreakpoint(bpType);
+ if (bp != null) {
+ bp.setEnabled(enabled);
}
}
diff --git a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataGroupVirtualFile.java b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataGroupVirtualFile.java
index c44b49cd71b9..069ef03c8277 100644
--- a/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataGroupVirtualFile.java
+++ b/plugins/IdeaTestAssistant/src/com/intellij/testAssistant/TestDataGroupVirtualFile.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,7 +43,7 @@ public class TestDataGroupVirtualFile extends VirtualFile {
@Override
public String getName() {
final String prefix = StringUtil.commonPrefix(myBeforeFile.getName(), myAfterFile.getName());
- if (prefix.length() == 0) {
+ if (prefix.isEmpty()) {
return StringUtil.commonSuffix(myBeforeFile.getName(), myAfterFile.getName());
}
return prefix + "." + myBeforeFile.getExtension();
@@ -63,6 +63,7 @@ public class TestDataGroupVirtualFile extends VirtualFile {
return LocalFileSystem.getInstance();
}
+ @NotNull
@Override
public String getPath() {
return myBeforeFile.getPath();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
index dddb6e1d3988..4becc9723a65 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
@@ -2489,6 +2489,9 @@
<localInspection language="JAVA" suppressId="LockAcquiredButNotSafelyReleased" shortName="SafeLock" bundle="com.siyeh.InspectionGadgetsBundle"
key="safe.lock.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.threading.issues"
enabledByDefault="false" level="WARNING" implementationClass="com.siyeh.ig.threading.SafeLockInspection"/>
+ <localInspection language="JAVA" suppressId="SharedThreadLocalRandom" shortName="SharedThreadLocalRandom" bundle="com.siyeh.InspectionGadgetsBundle"
+ key="shared.thread.local.random.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.threading.issues"
+ enabledByDefault="false" level="WARNING" implementationClass="com.siyeh.ig.threading.SharedThreadLocalRandomInspection"/>
<localInspection language="JAVA" shortName="SignalWithoutCorrespondingAwait" bundle="com.siyeh.InspectionGadgetsBundle"
key="signal.without.corresponding.await.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.threading.issues" enabledByDefault="false" level="WARNING"
@@ -2640,6 +2643,10 @@
bundle="com.siyeh.InspectionGadgetsBundle" key="parameter.hides.member.variable.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.visibility.issues" enabledByDefault="false"
level="WARNING" implementationClass="com.siyeh.ig.visibility.ParameterHidingMemberVariableInspection"/>
+ <localInspection language="JAVA" suppressId="LambdaParameterHidesMemberVariable" shortName="LambdaParameterHidingMemberVariable"
+ bundle="com.siyeh.InspectionGadgetsBundle" key="lambda.parameter.hides.member.variable.display.name"
+ groupBundle="messages.InspectionsBundle" groupKey="group.names.visibility.issues" enabledByDefault="false"
+ level="WARNING" implementationClass="com.siyeh.ig.visibility.LambdaParameterHidingMemberVariableInspection"/>
</extensions>
<application-components>
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
index 7f61b374c9a9..013cf2344b2a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
@@ -1157,7 +1157,7 @@ local.variable.naming.convention.problem.descriptor.long=Local variable name <co
local.variable.naming.convention.problem.descriptor.regex.mismatch=Local variable name <code>#ref</code> doesn''t match regex ''{0}'' #loc
local.variable.naming.convention.ignore.option=Ignore for-loop parameters
local.variable.naming.convention.ignore.catch.option=Ignore 'catch' block parameters
-method.names.differ.only.by.case.problem.descriptor=Method names <code>#ref</code> and ''{0}'' differ only by case #loc
+method.names.differ.only.by.case.problem.descriptor=Method name <code>#ref</code> and method name ''{0}'' differ only by case #loc
parameter.name.differs.from.overridden.parameter.ignore.character.option=Ignore if overridden parameter contains only one character
parameter.name.differs.from.overridden.parameter.ignore.library.option=Ignore if overridden parameter is from a library
parameter.name.differs.from.overridden.parameter.problem.descriptor=Parameter name <code>#ref</code> is different from parameter ''{0}'' overridden #loc
@@ -2066,3 +2066,8 @@ implicit.default.charset.usage.constructor.problem.descriptor=<code>new #ref()</
interface.may.be.annotated.functional.display.name=Interface may be annotated @FunctionalInterface
interface.may.be.annotated.functional.problem.descriptor=Interface <code>#ref</code> may be annotated with @FunctionalInterface
only.report.public.methods.option=Only report 'public' methods
+lambda.parameter.hides.member.variable.display.name=Lambda parameter hides field
+lambda.parameter.hides.member.variable.problem.descriptor=Lambda parameter <code>#ref</code> hides field in class ''{0}'' #loc
+shared.thread.local.random.display.name='ThreadLocalRandom' instance might be shared
+shared.thread.local.random.problem.descriptor='ThreadLocalRandom' instance might be shared between threads
+
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 9ef4c14e4a84..31a7987f40f1 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.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.
@@ -23,7 +23,6 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
-import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Query;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.InspectionGadgetsFix;
@@ -46,8 +45,7 @@ public class ExtractParameterAsLocalVariableFix
}
@Override
- public void doFix(Project project, ProblemDescriptor descriptor)
- throws IncorrectOperationException {
+ public void doFix(Project project, ProblemDescriptor descriptor) {
final PsiReferenceExpression parameterReference =
(PsiReferenceExpression)descriptor.getPsiElement();
final PsiElement target = parameterReference.resolve();
@@ -79,6 +77,10 @@ public class ExtractParameterAsLocalVariableFix
body = forBody;
}
}
+ else if (declarationScope instanceof PsiLambdaExpression) {
+ final PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)declarationScope;
+ body = lambdaExpression.getBody();
+ }
else {
return;
}
@@ -125,15 +127,16 @@ public class ExtractParameterAsLocalVariableFix
replaceVariableName(child, firstReference,
variableName, parameterName, buffer);
}
+ if (body instanceof PsiExpression) { // expression lambda
+ buffer.insert(0, "return ");
+ buffer.append(';');
+ }
final String replacementText;
if (newDeclarationCreated) {
replacementText = "{" + buffer + '}';
}
else {
- final PsiType type = parameterReference.getType();
- if (type == null) {
- return;
- }
+ final PsiType type = parameter.getType();
final String className = type.getCanonicalText();
replacementText = '{' + className + ' ' + variableName + " = " +
parameterName + ';' + buffer + '}';
@@ -141,8 +144,7 @@ public class ExtractParameterAsLocalVariableFix
final PsiElementFactory elementFactory =
JavaPsiFacade.getInstance(project).getElementFactory();
final PsiCodeBlock block =
- elementFactory.createCodeBlockFromText(
- replacementText, null);
+ elementFactory.createCodeBlockFromText(replacementText, declarationScope);
body.replace(block);
codeStyleManager.reformat(declarationScope);
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ControlFlowUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ControlFlowUtils.java
index 278c07e980c0..3741d260dae6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ControlFlowUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ControlFlowUtils.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.
@@ -35,7 +35,7 @@ public class ControlFlowUtils {
}
else if (statement instanceof PsiExpressionListStatement || statement instanceof PsiEmptyStatement ||
statement instanceof PsiAssertStatement || statement instanceof PsiDeclarationStatement ||
- statement instanceof PsiSwitchLabelStatement) {
+ statement instanceof PsiSwitchLabelStatement || statement instanceof PsiForeachStatement) {
return true;
}
else if (statement instanceof PsiExpressionStatement) {
@@ -63,9 +63,6 @@ public class ControlFlowUtils {
else if (statement instanceof PsiForStatement) {
return forStatementMayCompleteNormally((PsiForStatement)statement);
}
- else if (statement instanceof PsiForeachStatement) {
- return foreachStatementMayCompleteNormally((PsiForeachStatement)statement);
- }
else if (statement instanceof PsiWhileStatement) {
return whileStatementMayCompleteNormally((PsiWhileStatement)statement);
}
@@ -130,10 +127,6 @@ public class ControlFlowUtils {
return Boolean.TRUE != value;
}
- private static boolean foreachStatementMayCompleteNormally(@NotNull PsiForeachStatement loopStatement) {
- return true;
- }
-
private static boolean switchStatementMayCompleteNormally(@NotNull PsiSwitchStatement switchStatement) {
if (statementIsBreakTarget(switchStatement)) {
return true;
@@ -524,7 +517,7 @@ public class ControlFlowUtils {
}
}
- private static class SystemExitFinder extends JavaRecursiveElementVisitor {
+ private static class SystemExitFinder extends JavaRecursiveElementWalkingVisitor {
private boolean m_found = false;
@@ -564,7 +557,7 @@ public class ControlFlowUtils {
}
}
- private static class ReturnFinder extends JavaRecursiveElementVisitor {
+ private static class ReturnFinder extends JavaRecursiveElementWalkingVisitor {
private boolean m_found = false;
@@ -587,7 +580,7 @@ public class ControlFlowUtils {
}
}
- private static class BreakFinder extends JavaRecursiveElementVisitor {
+ private static class BreakFinder extends JavaRecursiveElementWalkingVisitor {
private boolean m_found = false;
private final PsiStatement m_target;
@@ -637,7 +630,7 @@ public class ControlFlowUtils {
}
}
- private static class ContinueFinder extends JavaRecursiveElementVisitor {
+ private static class ContinueFinder extends JavaRecursiveElementWalkingVisitor {
private boolean m_found = false;
private final PsiStatement m_target;
@@ -687,7 +680,7 @@ public class ControlFlowUtils {
}
}
- private static class MethodCallFinder extends JavaRecursiveElementVisitor {
+ private static class MethodCallFinder extends JavaRecursiveElementWalkingVisitor {
private final String containingClassName;
private final PsiType returnType;
@@ -728,7 +721,7 @@ public class ControlFlowUtils {
}
}
- private static class ContinueToAncestorFinder extends JavaRecursiveElementVisitor {
+ private static class ContinueToAncestorFinder extends JavaRecursiveElementWalkingVisitor {
private final PsiStatement statement;
private boolean found = false;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java
index c14da9f55373..ad5ecc2351f3 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java
@@ -153,86 +153,59 @@ public class ExpectedTypeUtils {
}
@Override
- public void visitBinaryExpression(@NotNull PsiBinaryExpression binaryExpression) {
- final PsiExpression rhs = binaryExpression.getROperand();
- if (rhs == null) {
- expectedType = null;
- return;
- }
- final PsiExpression lhs = binaryExpression.getLOperand();
- PsiType lhsType = lhs.getType();
- if (lhsType == null) {
- expectedType = null;
- return;
- }
- PsiType rhsType = rhs.getType();
- if (rhsType == null) {
- expectedType = null;
- return;
+ public void visitPolyadicExpression(@NotNull PsiPolyadicExpression polyadicExpression) {
+ final PsiExpression[] operands = polyadicExpression.getOperands();
+ for (PsiExpression operand : operands) {
+ if (operand == null || operand.getType() == null) {
+ expectedType = null;
+ return;
+ }
}
- final IElementType tokenType = binaryExpression.getOperationTokenType();
- final PsiType type = binaryExpression.getType();
+ final IElementType tokenType = polyadicExpression.getOperationTokenType();
+ final PsiType type = polyadicExpression.getType();
+ final PsiType wrappedExpressionType = wrappedExpression.getType();
if (TypeUtils.isJavaLangString(type) || isArithmeticOperation(tokenType) || isBooleanOperation(tokenType)) {
expectedType = type;
}
else if (isShiftOperation(tokenType)) {
- if (lhs == wrappedExpression) {
- expectedType = unaryNumericPromotion(lhsType);
- }
- else {
- expectedType = unaryNumericPromotion(rhsType);
- }
+ expectedType = unaryNumericPromotion(wrappedExpressionType);
}
- else if (ComparisonUtils.isEqualityComparison(binaryExpression)) {
+ else if (ComparisonUtils.isEqualityComparison(polyadicExpression)) {
// JLS 15.21.1 Numerical Equality Operators == and !=
- final PsiType wrappedExpressionType = wrappedExpression.getType();
if (TypeConversionUtil.isPrimitiveAndNotNull(wrappedExpressionType)) {
expectedType = wrappedExpressionType;
- return;
}
- if (lhs == wrappedExpression) {
- if (TypeConversionUtil.isPrimitiveAndNotNull(rhsType)) {
+ else if (operands.length > 2) {
+ expectedType = PsiPrimitiveType.getUnboxedType(wrappedExpressionType);
+ }
+ else if (operands[0] == wrappedExpression) {
+ if (TypeConversionUtil.isPrimitiveAndNotNull(operands[1].getType())) {
expectedType = PsiPrimitiveType.getUnboxedType(wrappedExpressionType);
- return;
}
- expectedType = TypeUtils.getObjectType(wrappedExpression);
+ else {
+ expectedType = TypeUtils.getObjectType(wrappedExpression);
+ }
}
else {
- if (TypeConversionUtil.isPrimitiveAndNotNull(lhsType)) {
+ if (TypeConversionUtil.isPrimitiveAndNotNull(operands[0].getType())) {
expectedType = PsiPrimitiveType.getUnboxedType(wrappedExpressionType);
- return;
- }
- expectedType = TypeUtils.getObjectType(wrappedExpression);
+ }
+ else {
+ expectedType = TypeUtils.getObjectType(wrappedExpression);
+ }
}
}
else if (ComparisonUtils.isComparisonOperation(tokenType)) {
- if (lhs == wrappedExpression && !TypeConversionUtil.isPrimitiveAndNotNull(lhsType)) {
- lhsType = PsiPrimitiveType.getUnboxedType(lhsType);
- if (lhsType == null) {
- expectedType = null;
- return;
- }
+ if (operands.length != 2) {
+ expectedType = null;
+ return;
}
- if (rhs == wrappedExpression && !TypeConversionUtil.isPrimitiveAndNotNull(rhsType)) {
- rhsType = PsiPrimitiveType.getUnboxedType(rhsType);
- if (rhsType == null) {
- expectedType = null;
+ else if (!TypeConversionUtil.isPrimitiveAndNotNull(wrappedExpressionType)) {
+ if (PsiPrimitiveType.getUnboxedType(wrappedExpressionType) == null) {
return;
}
}
- // JLS 5.6.2 Binary Numeric Promotion
- if (PsiType.DOUBLE.equals(lhsType) || PsiType.DOUBLE.equals(rhsType)) {
- expectedType = PsiType.DOUBLE;
- }
- else if (PsiType.FLOAT.equals(lhsType) || PsiType.FLOAT.equals(rhsType)) {
- expectedType = PsiType.FLOAT;
- }
- else if (PsiType.LONG.equals(lhsType) || PsiType.LONG.equals(rhsType)) {
- expectedType = PsiType.LONG;
- }
- else {
- expectedType = PsiType.INT;
- }
+ expectedType = TypeConversionUtil.binaryNumericPromotion(operands[0].getType(), operands[1].getType());
}
else {
expectedType = null;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ImportUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ImportUtils.java
index 6301e83eb0fd..8d52a8619dc5 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ImportUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ImportUtils.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.
@@ -19,8 +19,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleSettingsFacade;
import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.*;
+import com.intellij.psi.util.InheritanceUtil;
import com.siyeh.HardcodedMethodConstants;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -247,20 +247,22 @@ public class ImportUtils {
continue;
}
final PsiElement element = importReference.resolve();
- if (element == null || !(element instanceof PsiPackage)) {
+ if (!(element instanceof PsiPackage)) {
continue;
}
final PsiPackage aPackage = (PsiPackage)element;
- if (!strict) {
- return aPackage.containsClassNamed(shortName);
+ if (!strict && aPackage.containsClassNamed(shortName)) {
+ return true;
}
- final PsiClass[] classes = aPackage.findClassByShortName(shortName, file.getResolveScope());
- for (final PsiClass aClass : classes) {
- final String qualifiedClassName = aClass.getQualifiedName();
- if (qualifiedClassName == null || fqName.equals(qualifiedClassName)) {
- continue;
+ else {
+ final PsiClass[] classes = aPackage.findClassByShortName(shortName, file.getResolveScope());
+ for (final PsiClass aClass : classes) {
+ final String qualifiedClassName = aClass.getQualifiedName();
+ if (qualifiedClassName == null || fqName.equals(qualifiedClassName)) {
+ continue;
+ }
+ return containsConflictingReference(file, qualifiedClassName);
}
- return containsConflictingReference(file, qualifiedClassName);
}
}
return hasJavaLangImportConflict(fqName, file);
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SideEffectChecker.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SideEffectChecker.java
index af04c02d6e79..5063ef7c2ea7 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SideEffectChecker.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SideEffectChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2006 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.
@@ -31,7 +31,7 @@ public class SideEffectChecker {
return visitor.mayHaveSideEffects();
}
- private static class SideEffectsVisitor extends JavaRecursiveElementVisitor {
+ private static class SideEffectsVisitor extends JavaRecursiveElementWalkingVisitor {
private boolean mayHaveSideEffects = false;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/VariableAccessUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/VariableAccessUtils.java
index e097d58f8301..b8e7b7c183d8 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/VariableAccessUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/VariableAccessUtils.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.
@@ -20,6 +20,9 @@ import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
public class VariableAccessUtils {
@@ -446,4 +449,43 @@ public class VariableAccessUtils {
}
return child;
}
+
+ public static Set<PsiVariable> collectUsedVariables(PsiElement context) {
+ if (context == null) {
+ return Collections.emptySet();
+ }
+ final VariableCollectingVisitor visitor = new VariableCollectingVisitor();
+ context.accept(visitor);
+ return visitor.getUsedVariables();
+ }
+
+ public static boolean isAnyVariableAssigned(@NotNull Collection<PsiVariable> variables, @Nullable PsiElement context) {
+ if (context == null) {
+ return false;
+ }
+ final VariableAssignedVisitor visitor = new VariableAssignedVisitor(variables, true);
+ context.accept(visitor);
+ return visitor.isAssigned();
+ }
+
+ private static class VariableCollectingVisitor extends JavaRecursiveElementVisitor {
+
+ private final Set<PsiVariable> usedVariables = new HashSet();
+
+ @Override
+ public void visitReferenceExpression(
+ PsiReferenceExpression expression) {
+ super.visitReferenceExpression(expression);
+ final PsiElement target = expression.resolve();
+ if (!(target instanceof PsiVariable)) {
+ return;
+ }
+ final PsiVariable variable = (PsiVariable)target;
+ usedVariables.add(variable);
+ }
+
+ public Set<PsiVariable> getUsedVariables() {
+ return usedVariables;
+ }
+ }
} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/VariableAssignedVisitor.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/VariableAssignedVisitor.java
index 0a22ef3fde97..279400f3a653 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/VariableAssignedVisitor.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/VariableAssignedVisitor.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.
@@ -20,16 +20,25 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NotNull;
+import java.util.Collection;
+import java.util.Collections;
+
public class VariableAssignedVisitor extends JavaRecursiveElementWalkingVisitor {
- @NotNull private final PsiVariable variable;
+ @NotNull private final Collection<PsiVariable> variables;
private final boolean recurseIntoClasses;
private final boolean checkUnaryExpressions;
private boolean assigned = false;
private PsiElement excludedElement = null;
+ public VariableAssignedVisitor(@NotNull Collection<PsiVariable> variables, boolean recurseIntoClasses) {
+ this.variables = variables;
+ checkUnaryExpressions = true;
+ this.recurseIntoClasses = recurseIntoClasses;
+ }
+
public VariableAssignedVisitor(@NotNull PsiVariable variable, boolean recurseIntoClasses) {
- this.variable = variable;
+ variables = Collections.singleton(variable);
final PsiType type = variable.getType();
checkUnaryExpressions = TypeConversionUtil.isNumericType(type);
this.recurseIntoClasses = recurseIntoClasses;
@@ -58,8 +67,11 @@ public class VariableAssignedVisitor extends JavaRecursiveElementWalkingVisitor
}
super.visitAssignmentExpression(assignment);
final PsiExpression lhs = assignment.getLExpression();
- if (VariableAccessUtils.evaluatesToVariable(lhs, variable)) {
- assigned = true;
+ for (PsiVariable variable : variables) {
+ if (VariableAccessUtils.evaluatesToVariable(lhs, variable)) {
+ assigned = true;
+ break;
+ }
}
}
@@ -85,8 +97,11 @@ public class VariableAssignedVisitor extends JavaRecursiveElementWalkingVisitor
return;
}
final PsiExpression operand = prefixExpression.getOperand();
- if (VariableAccessUtils.evaluatesToVariable(operand, variable)) {
- assigned = true;
+ for (PsiVariable variable : variables) {
+ if (VariableAccessUtils.evaluatesToVariable(operand, variable)) {
+ assigned = true;
+ break;
+ }
}
}
@@ -104,8 +119,11 @@ public class VariableAssignedVisitor extends JavaRecursiveElementWalkingVisitor
return;
}
final PsiExpression operand = postfixExpression.getOperand();
- if (VariableAccessUtils.evaluatesToVariable(operand, variable)) {
- assigned = true;
+ for (PsiVariable variable : variables) {
+ if (VariableAccessUtils.evaluatesToVariable(operand, variable)) {
+ assigned = true;
+ break;
+ }
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/SharedThreadLocalRandomInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/SharedThreadLocalRandomInspection.java
new file mode 100644
index 000000000000..97adc033c5b1
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/SharedThreadLocalRandomInspection.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.threading;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.psiutils.ParenthesesUtils;
+import com.siyeh.ig.psiutils.VariableAccessUtils;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class SharedThreadLocalRandomInspection extends BaseInspection {
+ @Nls
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return InspectionGadgetsBundle.message("shared.thread.local.random.display.name");
+ }
+
+ @NotNull
+ @Override
+ protected String buildErrorString(Object... infos) {
+ return InspectionGadgetsBundle.message("shared.thread.local.random.problem.descriptor");
+ }
+
+ @Override
+ public BaseInspectionVisitor buildVisitor() {
+ return new SharedThreadLocalRandomVisitor();
+ }
+
+ private static class SharedThreadLocalRandomVisitor extends BaseInspectionVisitor {
+
+ @Override
+ public void visitMethodCallExpression(PsiMethodCallExpression expression) {
+ super.visitMethodCallExpression(expression);
+ final PsiReferenceExpression methodExpression = expression.getMethodExpression();
+ @NonNls final String name = methodExpression.getReferenceName();
+ if (!"current".equals(name)) {
+ return;
+ }
+ final PsiMethod method = expression.resolveMethod();
+ if (method == null) {
+ return;
+ }
+ final PsiClass aClass = method.getContainingClass();
+ if (!InheritanceUtil.isInheritor(aClass, "java.util.concurrent.ThreadLocalRandom")) {
+ return;
+ }
+ if (isArgumentToMethodCall(expression)) {
+ registerMethodCallError(expression);
+ }
+ else {
+ final PsiVariable variable = assignedToVariable(expression);
+ if (variable instanceof PsiField) {
+ registerMethodCallError(expression);
+ }
+ else if (variable instanceof PsiLocalVariable) {
+ final PsiCodeBlock context = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
+ if (VariableAccessUtils.variableIsPassedAsMethodArgument(variable, context) ||
+ VariableAccessUtils.variableIsUsedInInnerClass(variable, context)) {
+ registerMethodCallError(expression);
+ }
+ }
+ }
+ }
+
+ private static boolean isArgumentToMethodCall(PsiExpression expression) {
+ final PsiElement parent = ParenthesesUtils.getParentSkipParentheses(expression);
+ if (!(parent instanceof PsiExpressionList)) {
+ return false;
+ }
+ final PsiElement grandParent = parent.getParent();
+ return grandParent instanceof PsiMethodCallExpression;
+ }
+
+ private static PsiVariable assignedToVariable(PsiMethodCallExpression expression) {
+ final PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class);
+ if (parent instanceof PsiVariable) {
+ return (PsiVariable)parent;
+ }
+ if (!(parent instanceof PsiAssignmentExpression)) {
+ return null;
+ }
+ final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent;
+ final PsiExpression rhs = assignmentExpression.getRExpression();
+ if (!PsiTreeUtil.isAncestor(rhs, expression, false)) {
+ return null;
+ }
+ final PsiExpression lhs = ParenthesesUtils.stripParentheses(assignmentExpression.getLExpression());
+ if (!(lhs instanceof PsiReferenceExpression)) {
+ return null;
+ }
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)lhs;
+ final PsiElement target = referenceExpression.resolve();
+ if (!(target instanceof PsiVariable)) {
+ return null;
+ }
+ return (PsiVariable)target;
+ }
+ }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionBase.java
new file mode 100644
index 000000000000..5b245eccc0a0
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionBase.java
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ * 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.visibility;
+
+import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
+import com.intellij.psi.*;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.psiutils.ClassUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public class LambdaParameterHidingMemberVariableInspectionBase extends BaseInspection {
+
+ @SuppressWarnings("PublicField")
+ public boolean m_ignoreInvisibleFields = true;
+
+ @Override
+ @NotNull
+ public String getID() {
+ return "LambdaParameterHidesMemberVariable";
+ }
+
+ @Override
+ @NotNull
+ public String getDisplayName() {
+ return InspectionGadgetsBundle.message("lambda.parameter.hides.member.variable.display.name");
+ }
+
+ @Override
+ protected boolean buildQuickFixesOnlyForOnTheFlyErrors() {
+ return true;
+ }
+
+ @Override
+ @NotNull
+ public String buildErrorString(Object... infos) {
+ final PsiClass aClass = (PsiClass)infos[0];
+ return InspectionGadgetsBundle.message("lambda.parameter.hides.member.variable.problem.descriptor", aClass.getName());
+ }
+
+ @Override
+ public JComponent createOptionsPanel() {
+ final MultipleCheckboxOptionsPanel optionsPanel = new MultipleCheckboxOptionsPanel(this);
+ optionsPanel.addCheckbox(InspectionGadgetsBundle.message("parameter.hides.member.variable.ignore.superclass.option"),
+ "m_ignoreInvisibleFields");
+ return optionsPanel;
+ }
+
+ @Override
+ public BaseInspectionVisitor buildVisitor() {
+ return new LambdaParameterHidingMemberVariableVisitor();
+ }
+
+ private class LambdaParameterHidingMemberVariableVisitor extends BaseInspectionVisitor {
+
+ @Override
+ public void visitParameter(@NotNull PsiParameter variable) {
+ super.visitParameter(variable);
+ final PsiElement declarationScope = variable.getDeclarationScope();
+ if (!(declarationScope instanceof PsiLambdaExpression)) {
+ return;
+ }
+ final PsiClass aClass = checkFieldName(variable);
+ if (aClass == null) {
+ return;
+ }
+ registerVariableError(variable, aClass);
+ }
+
+ @Nullable
+ private PsiClass checkFieldName(PsiVariable variable) {
+ final String variableName = variable.getName();
+ if (variableName == null) {
+ return null;
+ }
+ PsiClass aClass = ClassUtils.getContainingClass(variable);
+ while (aClass != null) {
+ final PsiField[] fields = aClass.getAllFields();
+ for (PsiField field : fields) {
+ final String fieldName = field.getName();
+ if (!variableName.equals(fieldName)) {
+ continue;
+ }
+ if (!m_ignoreInvisibleFields || ClassUtils.isFieldVisible(field, aClass)) {
+ return aClass;
+ }
+ }
+ aClass = ClassUtils.getContainingClass(aClass);
+ }
+ return null;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspection.java
new file mode 100644
index 000000000000..4112dfe911da
--- /dev/null
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspection.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ * 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.visibility;
+
+import com.siyeh.ig.InspectionGadgetsFix;
+import com.siyeh.ig.fixes.RenameFix;
+
+public class LambdaParameterHidingMemberVariableInspection extends LambdaParameterHidingMemberVariableInspectionBase {
+ @Override
+ protected InspectionGadgetsFix buildFix(Object... infos) {
+ return new RenameFix();
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LambdaParameterHidingMemberVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LambdaParameterHidingMemberVariable.html
new file mode 100644
index 000000000000..3817e402e632
--- /dev/null
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LambdaParameterHidingMemberVariable.html
@@ -0,0 +1,11 @@
+<html>
+<body>
+Reports lambda parameters named identically to visible fields of the surrounding classes
+and their superclasses.
+<!-- tooltip end -->
+<p>
+Use the checkbox below to ignore fields that are not actually visible from the lambda expression, for example <b>private</b> fields
+<p>
+<small>New in 13.1</small>
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SharedThreadLocalRandom.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SharedThreadLocalRandom.html
new file mode 100644
index 000000000000..07ebccab4653
--- /dev/null
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SharedThreadLocalRandom.html
@@ -0,0 +1,15 @@
+<html>
+<body>
+Reports <b>java.util.concurrent.ThreadLocalRandom</b> instances which might be shared between threads.
+A <b>ThreadLocalRandom</b> might be shared between threads and is reported when it is assigned to a field,
+used as a method argument or assigned to a local variable and used in anonymous or nested classes.
+A <b>ThreadLocalRandom</b> should not be shared between threads because that is not thread-safe.
+<p>
+Usages of <b>ThreadLocalRandom</b> should typically look like <b>ThreadLocalRandom.current().nextInt(...)</b>
+(or <b>nextDouble(...)</b> etc.).
+When all usages are in this form, <b>ThreadLocalRandom</b> instances can not be used accidentally by multiple threads.
+<!-- tooltip end -->
+<p>
+<small>New in 13.1</small>
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadLocalNotStaticFinal.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadLocalNotStaticFinal.html
index 2cb9e55aa170..e78d9c1e5afe 100644
--- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadLocalNotStaticFinal.html
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadLocalNotStaticFinal.html
@@ -1,5 +1,6 @@
<html>
<body>
+Reports fields of type <b>java.lang.ThreadLocal</b> which are not declared <b>static final</b>.
In the most common case a <b>java.lang.ThreadLocal</b> instance
associates state with a thread. A non-static non-final
<b>java.lang.ThreadLocal</b> field associates state with
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/AutoUnboxing.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/AutoUnboxing.java
index a39bd53e4407..e598f0758a64 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/AutoUnboxing.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/AutoUnboxing.java
@@ -59,4 +59,8 @@ public class AutoUnboxing {
if ((boolean) b) {}
if ((int)n) {}
}
+
+ boolean polyadic() {
+ return true && Boolean.TRUE && true;
+ }
}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/expected.xml
index 431f5ca55078..a1ceb62b0486 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/expected.xml
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/expected.xml
@@ -106,4 +106,10 @@
<description>Auto-unboxing &lt;code&gt;n&lt;/code&gt; #loc</description>
</problem>
+ <problem>
+ <file>AutoUnboxing.java</file>
+ <line>64</line>
+ <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Auto-unboxing</problem_class>
+ <description>Auto-unboxing &lt;code&gt;Boolean.TRUE&lt;/code&gt; #loc</description>
+ </problem>
</problems> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/method_names_differ_only_by_case/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/method_names_differ_only_by_case/expected.xml
index 570e237c7063..3c9a518635fc 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/method_names_differ_only_by_case/expected.xml
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/method_names_differ_only_by_case/expected.xml
@@ -4,35 +4,35 @@
<file>MethodNamesDifferOnlyByCase.java</file>
<line>20</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Method names differing only by case</problem_class>
- <description>Method names &lt;code&gt;hashcode&lt;/code&gt; and 'hashCode' differ only by case #loc</description>
+ <description>Method name &lt;code&gt;hashcode&lt;/code&gt; and method name 'hashCode' differ only by case #loc</description>
</problem>
<problem>
<file>MethodNamesDifferOnlyByCase.java</file>
<line>30</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Method names differing only by case</problem_class>
- <description>Method names &lt;code&gt;xX&lt;/code&gt; and 'xx' differ only by case #loc</description>
+ <description>Method name &lt;code&gt;xX&lt;/code&gt; and method name 'xx' differ only by case #loc</description>
</problem>
<problem>
<file>MethodNamesDifferOnlyByCase.java</file>
<line>5</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Method names differing only by case</problem_class>
- <description>Method names &lt;code&gt;fooBar&lt;/code&gt; and 'fooBAr' differ only by case #loc</description>
+ <description>Method name &lt;code&gt;fooBar&lt;/code&gt; and method name 'fooBAr' differ only by case #loc</description>
</problem>
<problem>
<file>MethodNamesDifferOnlyByCase.java</file>
<line>10</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Method names differing only by case</problem_class>
- <description>Method names &lt;code&gt;fooBAr&lt;/code&gt; and 'fooBar' differ only by case #loc</description>
+ <description>Method name &lt;code&gt;fooBAr&lt;/code&gt; and method name 'fooBar' differ only by case #loc</description>
</problem>
<problem>
<file>MethodNamesDifferOnlyByCase.java</file>
<line>29</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Method names differing only by case</problem_class>
- <description>Method names &lt;code&gt;xx&lt;/code&gt; and 'xX' differ only by case #loc</description>
+ <description>Method name &lt;code&gt;xx&lt;/code&gt; and method name 'xX' differ only by case #loc</description>
</problem>
</problems> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java
index b56c340f5400..2ce63ec4814e 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.PluginPathManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
+import com.intellij.util.ArrayUtil;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -38,19 +39,33 @@ public abstract class IGQuickFixesTestCase extends JavaCodeInsightFixtureTestCas
protected void setUp() throws Exception {
super.setUp();
- final BaseInspection inspection = getInspection();
- if (inspection != null) {
- myFixture.enableInspections(inspection);
+ for (String environmentClass : getEnvironmentClasses()) {
+ myFixture.addClass(environmentClass);
}
+ myFixture.enableInspections(getInspections());
}
protected BaseInspection getInspection() {
return null;
}
+ protected BaseInspection[] getInspections() {
+ final BaseInspection inspection = getInspection();
+ if (inspection != null) {
+ return new BaseInspection[] {inspection};
+ }
+ return new BaseInspection[0];
+ }
+
+ @NonNls
+ @Language("JAVA")
+ protected String[] getEnvironmentClasses() {
+ return ArrayUtil.EMPTY_STRING_ARRAY;
+ }
+
@Override
protected void tuneFixture(final JavaModuleFixtureBuilder builder) throws Exception {
- builder.setLanguageLevel(LanguageLevel.JDK_1_7);
+ builder.setLanguageLevel(LanguageLevel.JDK_1_8);
}
@Override
@@ -79,16 +94,16 @@ public abstract class IGQuickFixesTestCase extends JavaCodeInsightFixtureTestCas
protected void doExpressionTest(
String hint,
- @Language(value = "JAVA", prefix = "class X {{System.out.print(", suffix = ");}}") @NotNull @NonNls String before,
- @Language(value = "JAVA", prefix = "class X {{System.out.print(", suffix = ");}}") @NotNull @NonNls String after) {
- doTest(hint, "class X {{System.out.print(" + before + ");}}", "class X {{System.out.print(" + after + ");}}");
+ @Language(value = "JAVA", prefix = "class $X$ {{System.out.print(", suffix = ");}}") @NotNull @NonNls String before,
+ @Language(value = "JAVA", prefix = "class $X$ {{System.out.print(", suffix = ");}}") @NotNull @NonNls String after) {
+ doTest(hint, "class $X$ {{System.out.print(" + before + ");}}", "class $X$ {{System.out.print(" + after + ");}}");
}
protected void doMemberTest(
String hint,
- @Language(value = "JAVA", prefix = "class X {", suffix = "}") @NotNull @NonNls String before,
- @Language(value = "JAVA", prefix = "class X {", suffix = "}") @NotNull @NonNls String after) {
- doTest(hint, "class X {" + before + "}", "class X {" + after + "}");
+ @Language(value = "JAVA", prefix = "class $X$ {", suffix = "}") @NotNull @NonNls String before,
+ @Language(value = "JAVA", prefix = "class $X$ {", suffix = "}") @NotNull @NonNls String after) {
+ doTest(hint, "class $X$ {" + before + "}", "class $X$ {\n " + after + "\n}");
}
protected void doTest(String hint, @Language("JAVA") @NotNull @NonNls String before, @Language("JAVA") @NotNull @NonNls String after) {
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFixTest.java
new file mode 100644
index 000000000000..b8b74aecf249
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFixTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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;
+
+import com.siyeh.InspectionGadgetsBundle;
+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.AssignmentToMethodParameterInspection;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class ExtractParameterAsLocalVariableFixTest extends IGQuickFixesTestCase {
+
+
+ @Override
+ protected BaseInspection[] getInspections() {
+ final AssignmentToForLoopParameterInspection inspection2 = new AssignmentToForLoopParameterInspection();
+ inspection2.m_checkForeachParameters = true;
+ return new BaseInspection[] {
+ new AssignmentToMethodParameterInspection(),
+ inspection2,
+ new AssignmentToCatchBlockParameterInspection()
+ };
+ }
+
+ @Override
+ protected String[] getEnvironmentClasses() {
+ return new String[] {"class A {}",
+ "public interface Function<T, R> {\n" +
+ " R apply(T t);" +
+ "}"};
+ }
+
+ public void testLambdaWithExpressionBody() {
+ doTest(
+ InspectionGadgetsBundle.message("extract.parameter.as.local.variable.quickfix"),
+ "class X {" +
+ " Function<A, A> f = (a) -> a/**/ = null;" +
+ "}",
+ "class X {" +
+ " Function<A, A> f = (a) -> {\n" +
+ " A a1 = a;\n" +
+ " return a1 = null;\n" +
+ "};}"
+ );
+ }
+
+ public void testSimpleMethod() {
+ doTest(
+ InspectionGadgetsBundle.message("extract.parameter.as.local.variable.quickfix"),
+ "class X {" +
+ " void m(String s) {" +
+ " /**/s = \"hello\";" +
+ " System.out.println(s);" +
+ " }" +
+ "}",
+ "class X {\n" +
+ " void m(String s) {\n" +
+ " String s1 = \"hello\";\n" +
+ " System.out.println(s1);\n" +
+ " }\n" +
+ "}"
+ );
+ }
+
+ public void testSimpleForeach() {
+ doTest(
+ InspectionGadgetsBundle.message("extract.parameter.as.local.variable.quickfix"),
+ "class X {" +
+ " void m() {" +
+ " for (String s : new String[]{\"one\", \"two\", \"three\"})" +
+ " s/**/ = \"four\";" +
+ "}}",
+ "class X {" +
+ " void m() {\n" +
+ " for (String s : new String[]{\"one\", \"two\", \"three\"}){\n" +
+ " String s1 = \"four\";\n" +
+ " }\n" +
+ "}}"
+ );
+ }
+
+ public void testSimleCatchBlock() {
+ doTest(
+ InspectionGadgetsBundle.message("extract.parameter.as.local.variable.quickfix"),
+ "class X {" +
+ " void m() {" +
+ " try (java.io.InputStream in = null) {" +
+ " } catch (java.io.IOException e) {" +
+ " e/**/ = null;" +
+ " System.out.println(e);" +
+ " }" +
+ " }" +
+ "}",
+ "class X {" +
+ " void m() {" +
+ " try (java.io.InputStream in = null) {" +
+ " } catch (java.io.IOException e) {\n" +
+ " java.io.IOException e1 = null;\n" +
+ " System.out.println(e1);\n" +
+ "}\n" +
+ "}}"
+ );
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/imports/UnusedImportInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/imports/UnusedImportInspectionTest.java
index 9f19674a7cee..d9dda5abc6a9 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/imports/UnusedImportInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/imports/UnusedImportInspectionTest.java
@@ -87,6 +87,21 @@ public class UnusedImportInspectionTest extends LightInspectionTestCase {
"}");
}
+ public void testNoWarn() {
+ addEnvironmentClass("package java.awt; public class List extends Component {}");
+ doTest("import javax.swing.*;\n" +
+ "import java.awt.*;\n" +
+ "import java.util.*;\n" +
+ "import java.util.List;\n" +
+ "\n" +
+ "class ImportTest extends Component {\n" +
+ "\n" +
+ " Collection<String> c;\n" +
+ " List<Integer> l;\n" +
+ " JComponent jc;\n" +
+ "}");
+ }
+
@Override
protected LocalInspectionTool getInspection() {
return new UnusedImportInspection();
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/threading/SharedThreadLocalRandomInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/threading/SharedThreadLocalRandomInspectionTest.java
new file mode 100644
index 000000000000..b15bc350fd6b
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/threading/SharedThreadLocalRandomInspectionTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.threading;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class SharedThreadLocalRandomInspectionTest extends LightInspectionTestCase {
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new SharedThreadLocalRandomInspection();
+ }
+
+ @Override
+ protected String[] getEnvironmentClasses() {
+ return new String[] {
+ "package java.util.concurrent;\n" +
+ "import java.util.Random;" +
+ "public class ThreadLocalRandom extends Random {" +
+ " public static ThreadLocalRandom current() {" +
+ " return null;" +
+ " }" +
+ "}"
+ };
+ }
+
+ public void testNoWarn() {
+ doStatementTest("System.out.println(java.util.concurrent.ThreadLocalRandom.current().nextInt());");
+ }
+
+ public void testArgument() {
+ doStatementTest("System.out.println(java.util.concurrent.ThreadLocalRandom./*'ThreadLocalRandom' instance might be shared between threads*/current/**/());");
+ }
+
+ public void testNoWarn2() {
+ doMemberTest("void m() {" +
+ " java.util.concurrent.ThreadLocalRandom r = java.util.concurrent.ThreadLocalRandom.current();" +
+ "}");
+ }
+
+ public void testNestedClass() {
+ doMemberTest("void m() {" +
+ " java.util.concurrent.ThreadLocalRandom r = java.util.concurrent.ThreadLocalRandom./*'ThreadLocalRandom' instance might be shared between threads*/current/**/();" +
+ " class Z extends Thread {" +
+ " public void run() {" +
+ " System.out.println(r.nextInt(1));" +
+ " }" +
+ " }" +
+ "}");
+ }
+
+ public void testAssignmentToField() {
+ doTest("import java.util.concurrent.ThreadLocalRandom;" +
+ "class A {" +
+ " private ThreadLocalRandom r;" +
+ " void m() {" +
+ " r = ThreadLocalRandom./*'ThreadLocalRandom' instance might be shared between threads*/current/**/();" +
+ " }" +
+ "}");
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionTest.java
new file mode 100644
index 000000000000..e7c3b75f1a6d
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/LambdaParameterHidingMemberVariableInspectionTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.visibility;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class LambdaParameterHidingMemberVariableInspectionTest extends LightInspectionTestCase {
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new LambdaParameterHidingMemberVariableInspection();
+ }
+
+ @Override
+ protected String[] getEnvironmentClasses() {
+ return new String[] {"package java.util.function;" +
+ "public interface Function<T, R> {" +
+ " R apply(T t);" +
+ "}"};
+ }
+
+ public void testSimple() {
+ doTest("import java.util.function.Function;" +
+ "class X {" +
+ " private String s;" +
+ "" +
+ " void m() {" +
+ " Function<String, String> f = (/*Lambda parameter 's' hides field in class 'X'*/s/**/) -> null;" +
+ " }" +
+ "}");
+ }
+}
diff --git a/plugins/IntelliLang/src/META-INF/plugin.xml b/plugins/IntelliLang/src/META-INF/plugin.xml
index 34731356c845..b62e139cc20e 100644
--- a/plugins/IntelliLang/src/META-INF/plugin.xml
+++ b/plugins/IntelliLang/src/META-INF/plugin.xml
@@ -2,7 +2,19 @@
<name>IntelliLang</name>
<id>org.intellij.intelliLang</id>
<vendor>JetBrains</vendor>
- <description><![CDATA[User configurable language injection support (originally developed by Sascha Weinreuter sascha.weinreuter@cit.de)]]></description>
+ <description>
+ <![CDATA[
+ Enables user configurable language injection support (originally developed by Sascha Weinreuter sascha.weinreuter@cit.de)
+ The following features are available:
+ <ul>
+ <li>Language injection</li>
+ <li>Pattern validation</li>
+ <li>Regular expression support</li>
+ <li>Language Injections page in the Settings/Preferences dialog.</li>
+ <li>Ability to edit injected code in the special scratch-pad editor.</l>
+ </ul>
+ ]]>
+ </description>
<version>8.0</version>
<depends optional="true" config-file="intellilang-xpath-support.xml">XPathView</depends>
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/BaseBracesIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/BaseBracesIntention.java
index 9b1e57afe720..ecaa8acad5cf 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/BaseBracesIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/BaseBracesIntention.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,7 +15,6 @@
*/
package com.siyeh.ipp.braces;
-import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.siyeh.IntentionPowerPackBundle;
import com.siyeh.ipp.base.MutablyNamedIntention;
@@ -57,59 +56,21 @@ public abstract class BaseBracesIntention extends MutablyNamedIntention {
final PsiElement parent = element.getParent();
if (parent instanceof PsiIfStatement) {
final PsiIfStatement ifStatement = (PsiIfStatement)parent;
- if (isBetweenThen(ifStatement, element)) {
- return ifStatement.getThenBranch();
- }
-
- if (isBetweenElse(ifStatement, element)) {
+ final PsiStatement thenBranch = ifStatement.getThenBranch();
+ final int offset = element.getTextOffset();
+ if (thenBranch != null && offset > thenBranch.getTextOffset()) {
+ final PsiKeyword elseElement = ifStatement.getElseElement();
+ if (elseElement == null || offset < elseElement.getTextOffset()) {
+ // no 'else' branch or after 'then' branch but before 'else' keyword
+ return null;
+ }
return ifStatement.getElseBranch();
}
+ return thenBranch;
}
- if (parent instanceof PsiWhileStatement) {
- return ((PsiWhileStatement)parent).getBody();
- }
- if (parent instanceof PsiDoWhileStatement) {
- return ((PsiDoWhileStatement)parent).getBody();
- }
- if (parent instanceof PsiForStatement) {
- return ((PsiForStatement)parent).getBody();
- }
- if (parent instanceof PsiForeachStatement) {
- return ((PsiForeachStatement)parent).getBody();
+ if (parent instanceof PsiLoopStatement) {
+ return ((PsiLoopStatement)parent).getBody();
}
return null;
}
-
- private static boolean isBetweenThen(@NotNull PsiIfStatement ifStatement, @NotNull PsiElement element) {
- final PsiElement rParenth = ifStatement.getRParenth();
- final PsiElement elseElement = ifStatement.getElseElement();
-
- if (rParenth == null) {
- return false;
- }
-
- if (elseElement == null) {
- return true;
- }
-
- final TextRange rParenthTextRangeTextRange = rParenth.getTextRange();
- final TextRange elseElementTextRange = elseElement.getTextRange();
- final TextRange elementTextRange = element.getTextRange();
-
- return new TextRange(rParenthTextRangeTextRange.getEndOffset(), elseElementTextRange.getStartOffset()).contains(elementTextRange);
- }
-
- private static boolean isBetweenElse(@NotNull PsiIfStatement ifStatement, @NotNull PsiElement element) {
- final PsiElement elseElement = ifStatement.getElseElement();
-
- if (elseElement == null) {
- return false;
- }
-
- final TextRange ifStatementTextRange = ifStatement.getTextRange();
- final TextRange elseElementTextRange = elseElement.getTextRange();
- final TextRange elementTextRange = element.getTextRange();
-
- return new TextRange(elseElementTextRange.getStartOffset(), ifStatementTextRange.getEndOffset()).contains(elementTextRange);
- }
}
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitMultiCatchIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitMultiCatchIntention.java
index f0288078a691..c58edc18b433 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitMultiCatchIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitMultiCatchIntention.java
@@ -17,12 +17,15 @@ package com.siyeh.ipp.exceptions;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
+import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.ipp.base.Intention;
import com.siyeh.ipp.base.PsiElementPredicate;
import org.jetbrains.annotations.NotNull;
-import static com.intellij.psi.PsiAnnotation.TargetType;
+import java.util.List;
+
+import static com.intellij.util.ObjectUtils.assertNotNull;
public class SplitMultiCatchIntention extends Intention {
@@ -52,25 +55,28 @@ public class SplitMultiCatchIntention extends Intention {
return;
}
- final PsiModifierList modifierList = parameter.getModifierList();
- if (modifierList != null) {
- for (PsiAnnotation annotation : modifierList.getAnnotations()) {
- if (PsiImplUtil.findApplicableTarget(annotation, TargetType.TYPE_USE) == TargetType.TYPE_USE) {
- annotation.delete();
- }
- }
- }
-
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(element.getProject());
- for (PsiType disjunction : ((PsiDisjunctionType)type).getDisjunctions()) {
+ final List<PsiTypeElement> disjunctions = PsiTreeUtil.getChildrenOfTypeAsList(parameter.getTypeElement(), PsiTypeElement.class);
+ for (int i = 0; i < disjunctions.size(); i++) {
final PsiCatchSection copy = (PsiCatchSection)catchSection.copy();
- final PsiParameter copyParameter = copy.getParameter();
- assert copyParameter != null : copy.getText();
- final PsiTypeElement typeElement = copyParameter.getTypeElement();
- assert typeElement != null : copyParameter.getText();
- final PsiTypeElement newTypeElement = factory.createTypeElement(disjunction);
+
+ final PsiTypeElement typeElement = assertNotNull(assertNotNull(copy.getParameter()).getTypeElement());
+ final PsiTypeElement newTypeElement = factory.createTypeElementFromText(disjunctions.get(i).getText(), catchSection);
typeElement.replace(newTypeElement);
+
grandParent.addBefore(copy, catchSection);
+
+ if (i == 0) {
+ // clear the original from type annotations: they belong to the first disjunction and should not appear in others
+ final PsiModifierList modifierList = parameter.getModifierList();
+ if (modifierList != null) {
+ for (PsiAnnotation annotation : modifierList.getAnnotations()) {
+ if (PsiImplUtil.findApplicableTarget(annotation, PsiAnnotation.TargetType.TYPE_USE) == PsiAnnotation.TargetType.TYPE_USE) {
+ annotation.delete();
+ }
+ }
+ }
+ }
}
catchSection.delete();
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReverseForLoopDirectionIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReverseForLoopDirectionIntention.java
index 35404ae2f77d..d76eaaffc86c 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReverseForLoopDirectionIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReverseForLoopDirectionIntention.java
@@ -22,9 +22,9 @@ import com.intellij.util.IncorrectOperationException;
import com.siyeh.ig.psiutils.ComparisonUtils;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.ParenthesesUtils;
+import com.siyeh.ig.psiutils.VariableAccessUtils;
import com.siyeh.ipp.base.Intention;
import com.siyeh.ipp.base.PsiElementPredicate;
-import com.siyeh.ipp.psiutils.VariableAccessUtils;
import org.jetbrains.annotations.NotNull;
public class ReverseForLoopDirectionIntention extends Intention {
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReverseForLoopDirectionPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReverseForLoopDirectionPredicate.java
index f37d90013490..ef8b6d73093c 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReverseForLoopDirectionPredicate.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReverseForLoopDirectionPredicate.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2013 Bas Leijdekkers
+ * Copyright 2009-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.
@@ -15,10 +15,14 @@
*/
package com.siyeh.ipp.forloop;
+import com.siyeh.ig.psiutils.ComparisonUtils;
+import com.siyeh.ig.psiutils.ParenthesesUtils;
+import com.siyeh.ig.psiutils.VariableAccessUtils;
import com.siyeh.ipp.base.PsiElementPredicate;
-import com.siyeh.ipp.psiutils.VariableAccessUtils;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
class ReverseForLoopDirectionPredicate implements PsiElementPredicate {
@@ -57,11 +61,109 @@ class ReverseForLoopDirectionPredicate implements PsiElementPredicate {
return false;
}
final PsiExpression condition = forStatement.getCondition();
- if (!VariableAccessUtils.isVariableCompared(variable, condition)) {
+ if (!isVariableCompared(variable, condition)) {
return false;
}
final PsiStatement update = forStatement.getUpdate();
- return VariableAccessUtils.isVariableIncrementOrDecremented(variable,
- update);
+ return isVariableIncrementOrDecremented(variable, update);
+ }
+
+ public static boolean isVariableCompared(
+ @NotNull PsiVariable variable, @Nullable PsiExpression expression) {
+ if (!(expression instanceof PsiBinaryExpression)) {
+ return false;
+ }
+ final PsiBinaryExpression binaryExpression =
+ (PsiBinaryExpression)expression;
+ final IElementType tokenType = binaryExpression.getOperationTokenType();
+ if (!ComparisonUtils.isComparisonOperation(tokenType)) {
+ return false;
+ }
+ final PsiExpression lhs = binaryExpression.getLOperand();
+ final PsiExpression rhs = binaryExpression.getROperand();
+ if (rhs == null) {
+ return false;
+ }
+ if (VariableAccessUtils.evaluatesToVariable(lhs, variable)) {
+ return true;
+ }
+ else if (VariableAccessUtils.evaluatesToVariable(rhs, variable)) {
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean isVariableIncrementOrDecremented(
+ @NotNull PsiVariable variable, @Nullable PsiStatement statement) {
+ if (!(statement instanceof PsiExpressionStatement)) {
+ return false;
+ }
+ final PsiExpressionStatement expressionStatement =
+ (PsiExpressionStatement)statement;
+ PsiExpression expression = expressionStatement.getExpression();
+ expression = ParenthesesUtils.stripParentheses(expression);
+ if (expression instanceof PsiPrefixExpression) {
+ final PsiPrefixExpression prefixExpression =
+ (PsiPrefixExpression)expression;
+ final IElementType tokenType = prefixExpression.getOperationTokenType();
+ if (!tokenType.equals(JavaTokenType.PLUSPLUS) &&
+ !tokenType.equals(JavaTokenType.MINUSMINUS)) {
+ return false;
+ }
+ final PsiExpression operand = prefixExpression.getOperand();
+ return VariableAccessUtils.evaluatesToVariable(operand, variable);
+ }
+ else if (expression instanceof PsiPostfixExpression) {
+ final PsiPostfixExpression postfixExpression =
+ (PsiPostfixExpression)expression;
+ final IElementType tokenType = postfixExpression.getOperationTokenType();
+ if (!tokenType.equals(JavaTokenType.PLUSPLUS) &&
+ !tokenType.equals(JavaTokenType.MINUSMINUS)) {
+ return false;
+ }
+ final PsiExpression operand = postfixExpression.getOperand();
+ return VariableAccessUtils.evaluatesToVariable(operand, variable);
+ }
+ else if (expression instanceof PsiAssignmentExpression) {
+ final PsiAssignmentExpression assignmentExpression =
+ (PsiAssignmentExpression)expression;
+ final IElementType tokenType =
+ assignmentExpression.getOperationTokenType();
+ PsiExpression lhs = assignmentExpression.getLExpression();
+ lhs = ParenthesesUtils.stripParentheses(lhs);
+ if (!VariableAccessUtils.evaluatesToVariable(lhs, variable)) {
+ return false;
+ }
+ PsiExpression rhs = assignmentExpression.getRExpression();
+ rhs = ParenthesesUtils.stripParentheses(rhs);
+ if (tokenType == JavaTokenType.EQ) {
+ if (!(rhs instanceof PsiBinaryExpression)) {
+ return false;
+ }
+ final PsiBinaryExpression binaryExpression =
+ (PsiBinaryExpression)rhs;
+ final IElementType token =
+ binaryExpression.getOperationTokenType();
+ if (!token.equals(JavaTokenType.PLUS) &&
+ !token.equals(JavaTokenType.MINUS)) {
+ return false;
+ }
+ PsiExpression lOperand = binaryExpression.getLOperand();
+ lOperand = ParenthesesUtils.stripParentheses(lOperand);
+ PsiExpression rOperand = binaryExpression.getROperand();
+ rOperand = ParenthesesUtils.stripParentheses(rOperand);
+ if (VariableAccessUtils.evaluatesToVariable(rOperand, variable)) {
+ return true;
+ }
+ else if (VariableAccessUtils.evaluatesToVariable(lOperand, variable)) {
+ return true;
+ }
+ }
+ else if (tokenType == JavaTokenType.PLUSEQ ||
+ tokenType == JavaTokenType.MINUSEQ) {
+ return true;
+ }
+ }
+ return false;
}
} \ No newline at end of file
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceAssignmentWithPostfixExpressionPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceAssignmentWithPostfixExpressionPredicate.java
index e239e85893af..89cd997e6822 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceAssignmentWithPostfixExpressionPredicate.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceAssignmentWithPostfixExpressionPredicate.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2013 Bas Leijdekkers
+ * Copyright 2009-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.
@@ -18,8 +18,8 @@ package com.siyeh.ipp.opassign;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.siyeh.ig.psiutils.ParenthesesUtils;
+import com.siyeh.ig.psiutils.VariableAccessUtils;
import com.siyeh.ipp.base.PsiElementPredicate;
-import com.siyeh.ipp.psiutils.VariableAccessUtils;
class ReplaceAssignmentWithPostfixExpressionPredicate implements PsiElementPredicate {
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceableWithOperatorAssignmentPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceableWithOperatorAssignmentPredicate.java
index 959c858c05f0..34a2d0851d24 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceableWithOperatorAssignmentPredicate.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceableWithOperatorAssignmentPredicate.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.
@@ -18,10 +18,10 @@ package com.siyeh.ipp.opassign;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiUtil;
-import com.siyeh.ipp.base.PsiElementPredicate;
import com.siyeh.ig.psiutils.EquivalenceChecker;
+import com.siyeh.ig.psiutils.SideEffectChecker;
+import com.siyeh.ipp.base.PsiElementPredicate;
import com.siyeh.ipp.psiutils.ErrorUtil;
-import com.siyeh.ipp.psiutils.SideEffectChecker;
class ReplaceableWithOperatorAssignmentPredicate implements PsiElementPredicate {
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ConditionalUtils.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ConditionalUtils.java
deleted file mode 100644
index 8d13fe20bee8..000000000000
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ConditionalUtils.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2003-2012 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.
- * 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.ipp.psiutils;
-
-import com.intellij.psi.*;
-import org.jetbrains.annotations.NonNls;
-
-public class ConditionalUtils {
-
- private ConditionalUtils() {}
-
- public static boolean isReturn(PsiStatement statement,
- @NonNls String value) {
- if (statement == null) {
- return false;
- }
- if (!(statement instanceof PsiReturnStatement)) {
- return false;
- }
- final PsiReturnStatement returnStatement =
- (PsiReturnStatement)statement;
- if (returnStatement.getReturnValue() == null) {
- return false;
- }
- final PsiExpression returnValue = returnStatement.getReturnValue();
- if (returnValue == null) {
- return false;
- }
- final String returnValueText = returnValue.getText();
- return value.equals(returnValueText);
- }
-
- public static boolean isAssignment(PsiStatement statement,
- @NonNls String value) {
- if (statement == null) {
- return false;
- }
- if (!(statement instanceof PsiExpressionStatement)) {
- return false;
- }
- final PsiExpressionStatement expressionStatement =
- (PsiExpressionStatement)statement;
- final PsiExpression expression = expressionStatement.getExpression();
- if (!(expression instanceof PsiAssignmentExpression)) {
- return false;
- }
- final PsiAssignmentExpression assignment =
- (PsiAssignmentExpression)expression;
- final PsiExpression rhs = assignment.getRExpression();
- if (rhs == null) {
- return false;
- }
- final String rhsText = rhs.getText();
- return value.equals(rhsText);
- }
-}
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ControlFlowUtils.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ControlFlowUtils.java
deleted file mode 100644
index 668444bd22c1..000000000000
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/ControlFlowUtils.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright 2003-2011 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.
- * 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.ipp.psiutils;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.*;
-
-public class ControlFlowUtils {
-
- private ControlFlowUtils() {
- }
-
- public static boolean statementMayCompleteNormally(PsiStatement statement) {
- if (statement instanceof PsiBreakStatement ||
- statement instanceof PsiContinueStatement ||
- statement instanceof PsiReturnStatement ||
- statement instanceof PsiThrowStatement) {
- return false;
- }
- else if (statement instanceof PsiExpressionListStatement ||
- statement instanceof PsiExpressionStatement ||
- statement instanceof PsiEmptyStatement ||
- statement instanceof PsiAssertStatement ||
- statement instanceof PsiDeclarationStatement) {
- return true;
- }
- else if (statement instanceof PsiForStatement) {
- final PsiForStatement loopStatement = (PsiForStatement)statement;
- final PsiExpression test = loopStatement.getCondition();
- return test != null && !isBooleanConstant(test, true) ||
- statementIsBreakTarget(loopStatement);
- }
- else if (statement instanceof PsiForeachStatement) {
- return true;
- }
- else if (statement instanceof PsiWhileStatement) {
- final PsiWhileStatement loopStatement =
- (PsiWhileStatement)statement;
- final PsiExpression test = loopStatement.getCondition();
- return !isBooleanConstant(test, true)
- || statementIsBreakTarget(loopStatement);
- }
- else if (statement instanceof PsiDoWhileStatement) {
- final PsiDoWhileStatement loopStatement =
- (PsiDoWhileStatement)statement;
- final PsiExpression test = loopStatement.getCondition();
- final PsiStatement body = loopStatement.getBody();
- return statementMayCompleteNormally(body) &&
- !isBooleanConstant(test, true)
- || statementIsBreakTarget(loopStatement);
- }
- else if (statement instanceof PsiSynchronizedStatement) {
- final PsiCodeBlock body =
- ((PsiSynchronizedStatement)statement).getBody();
- return codeBlockMayCompleteNormally(body);
- }
- else if (statement instanceof PsiBlockStatement) {
- final PsiCodeBlock codeBlock =
- ((PsiBlockStatement)statement).getCodeBlock();
- return codeBlockMayCompleteNormally(codeBlock);
- }
- else if (statement instanceof PsiLabeledStatement) {
- final PsiLabeledStatement labeledStatement =
- (PsiLabeledStatement)statement;
- final PsiStatement body = labeledStatement.getStatement();
- return statementMayCompleteNormally(body)
- || statementIsBreakTarget(body);
- }
- else if (statement instanceof PsiIfStatement) {
- final PsiIfStatement ifStatement = (PsiIfStatement)statement;
- final PsiStatement thenBranch = ifStatement.getThenBranch();
- if (statementMayCompleteNormally(thenBranch)) {
- return true;
- }
- final PsiStatement elseBranch = ifStatement.getElseBranch();
- return elseBranch == null ||
- statementMayCompleteNormally(elseBranch);
- }
- else if (statement instanceof PsiTryStatement) {
- final PsiTryStatement tryStatement = (PsiTryStatement)statement;
-
- final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock();
- if (finallyBlock != null) {
- if (!codeBlockMayCompleteNormally(finallyBlock)) {
- return false;
- }
- }
- final PsiCodeBlock tryBlock = tryStatement.getTryBlock();
- if (codeBlockMayCompleteNormally(tryBlock)) {
- return true;
- }
- final PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks();
- for (final PsiCodeBlock catchBlock : catchBlocks) {
- if (codeBlockMayCompleteNormally(catchBlock)) {
- return true;
- }
- }
- return false;
- }
- else if (statement instanceof PsiSwitchStatement) {
- final PsiSwitchStatement switchStatement =
- (PsiSwitchStatement)statement;
- if (statementIsBreakTarget(switchStatement)) {
- return true;
- }
- final PsiCodeBlock body = switchStatement.getBody();
- if (body == null) {
- return true;
- }
- final PsiStatement[] statements = body.getStatements();
- int lastNonLabelOffset = -1;
- final int lastStatementIndex = statements.length - 1;
- for (int i = lastStatementIndex; i >= 0; i--) {
- if (!(statements[i] instanceof PsiSwitchLabelStatement)) {
- lastNonLabelOffset = i;
- break;
- }
- }
- if (lastNonLabelOffset == -1) {
- return true; // it's all labels
- }
- else if (lastNonLabelOffset == lastStatementIndex) {
- return statementMayCompleteNormally(
- statements[lastStatementIndex]);
- }
- else {
- return true; // the last statement is a label
- }
- }
- else {
- return false;
- }
- }
-
- private static boolean codeBlockMayCompleteNormally(PsiCodeBlock block) {
- if (block == null) {
- return true;
- }
- final PsiStatement[] statements = block.getStatements();
- for (final PsiStatement statement : statements) {
- if (!statementMayCompleteNormally(statement)) {
- return false;
- }
- }
- return true;
- }
-
- private static boolean isBooleanConstant(PsiExpression expression,
- boolean b) {
- if (expression == null) {
- return false;
- }
- final Project project = expression.getProject();
- final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
- final PsiConstantEvaluationHelper constantEvaluationHelper =
- psiFacade.getConstantEvaluationHelper();
- final Object value =
- constantEvaluationHelper.computeConstantExpression
- (expression, false);
- if (!(value instanceof Boolean)) {
- return false;
- }
- final Boolean aBoolean = (Boolean)value;
- return aBoolean.booleanValue() == b;
- }
-
- private static boolean statementIsBreakTarget(PsiStatement statement) {
- if (statement == null) {
- return false;
- }
- final BreakTargetFinder breakFinder = new BreakTargetFinder(statement);
- statement.accept(breakFinder);
- return breakFinder.breakFound();
- }
-
- public static boolean statementContainsNakedBreak(PsiStatement statement) {
- if (statement == null) {
- return false;
- }
- final NakedBreakFinder breakFinder = new NakedBreakFinder();
- statement.accept(breakFinder);
- return breakFinder.breakFound();
- }
-
- private static class BreakTargetFinder
- extends JavaRecursiveElementWalkingVisitor {
-
- private boolean m_found = false;
- private final PsiStatement m_target;
-
- private BreakTargetFinder(PsiStatement target) {
- m_target = target;
- }
-
- public boolean breakFound() {
- return m_found;
- }
-
- @Override
- public void visitElement(PsiElement element) {
- if (m_found) {
- return;
- }
- super.visitElement(element);
- }
-
- @Override
- public void visitReferenceExpression(
- PsiReferenceExpression expression) {
- }
-
- @Override
- public void visitBreakStatement(PsiBreakStatement statement) {
- super.visitBreakStatement(statement);
- final PsiStatement exitedStatement =
- statement.findExitedStatement();
- if (exitedStatement == null) {
- return;
- }
- if (exitedStatement.equals(m_target)) {
- m_found = true;
- }
- }
- }
-
- private static class NakedBreakFinder
- extends JavaRecursiveElementWalkingVisitor {
-
- private boolean m_found = false;
-
- public boolean breakFound() {
- return m_found;
- }
-
- @Override
- public void visitElement(PsiElement element) {
- if (m_found) {
- return;
- }
- super.visitElement(element);
- }
-
- @Override
- public void visitReferenceExpression(
- PsiReferenceExpression expression) {
- }
-
- @Override
- public void visitBreakStatement(PsiBreakStatement statement) {
- if (statement.getLabelIdentifier() != null) {
- return;
- }
- m_found = true;
- }
-
- @Override
- public void visitDoWhileStatement(
- PsiDoWhileStatement statement) {
- // don't drill down
- }
-
- @Override
- public void visitForStatement(PsiForStatement statement) {
- // don't drill down
- }
-
- @Override
- public void visitForeachStatement(PsiForeachStatement statement) {
- // don't drill down
- }
-
- @Override
- public void visitWhileStatement(PsiWhileStatement statement) {
- // don't drill down
- }
-
- @Override
- public void visitSwitchStatement(
- PsiSwitchStatement statement) {
- // don't drill down
- }
- }
-} \ No newline at end of file
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/SideEffectChecker.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/SideEffectChecker.java
deleted file mode 100644
index 7940dd739ecb..000000000000
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/SideEffectChecker.java
+++ /dev/null
@@ -1,87 +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.ipp.psiutils;
-
-import com.intellij.psi.*;
-import com.intellij.psi.tree.IElementType;
-
-public class SideEffectChecker {
-
- private SideEffectChecker() {
- super();
- }
-
- public static boolean mayHaveSideEffects(PsiExpression exp) {
- final SideEffectsVisitor visitor = new SideEffectsVisitor();
- exp.accept(visitor);
- return visitor.mayHaveSideEffects();
- }
-
- private static class SideEffectsVisitor extends JavaRecursiveElementWalkingVisitor {
-
- private boolean mayHaveSideEffects = false;
-
- @Override
- public void visitElement(PsiElement element) {
- if (!mayHaveSideEffects) {
- super.visitElement(element);
- }
- }
-
- @Override
- public void visitMethodCallExpression(
- PsiMethodCallExpression expression) {
- mayHaveSideEffects = true;
- }
-
- @Override
- public void visitNewExpression(PsiNewExpression expression) {
- mayHaveSideEffects = true;
- }
-
- @Override
- public void visitAssignmentExpression(
- PsiAssignmentExpression expression) {
- mayHaveSideEffects = true;
- }
-
- @Override
- public void visitPrefixExpression(PsiPrefixExpression expression) {
- super.visitPrefixExpression(expression);
- final IElementType tokenType = expression.getOperationTokenType();
-
- if (tokenType.equals(JavaTokenType.PLUSPLUS) ||
- tokenType.equals(JavaTokenType.MINUSMINUS)) {
- mayHaveSideEffects = true;
- }
- }
-
- @Override
- public void visitPostfixExpression(PsiPostfixExpression expression) {
- super.visitPostfixExpression(expression);
- final IElementType tokenType = expression.getOperationTokenType();
-
- if (tokenType.equals(JavaTokenType.PLUSPLUS) ||
- tokenType.equals(JavaTokenType.MINUSMINUS)) {
- mayHaveSideEffects = true;
- }
- }
-
- public boolean mayHaveSideEffects() {
- return mayHaveSideEffects;
- }
- }
-} \ No newline at end of file
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/VariableAccessUtils.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/VariableAccessUtils.java
deleted file mode 100644
index 2ac8500bad4a..000000000000
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/VariableAccessUtils.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright 2009-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.
- * 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.ipp.psiutils;
-
-import com.intellij.psi.*;
-import com.intellij.psi.tree.IElementType;
-import com.siyeh.ig.psiutils.ComparisonUtils;
-import com.siyeh.ig.psiutils.ParenthesesUtils;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-public class VariableAccessUtils {
-
- private VariableAccessUtils() {
- }
-
- public static boolean isVariableCompared(
- @NotNull PsiVariable variable, @Nullable PsiExpression expression) {
- if (!(expression instanceof PsiBinaryExpression)) {
- return false;
- }
- final PsiBinaryExpression binaryExpression =
- (PsiBinaryExpression)expression;
- final IElementType tokenType = binaryExpression.getOperationTokenType();
- if (!ComparisonUtils.isComparisonOperation(tokenType)) {
- return false;
- }
- final PsiExpression lhs = binaryExpression.getLOperand();
- final PsiExpression rhs = binaryExpression.getROperand();
- if (rhs == null) {
- return false;
- }
- if (evaluatesToVariable(lhs, variable)) {
- return true;
- }
- else if (evaluatesToVariable(rhs, variable)) {
- return true;
- }
- return false;
- }
-
- public static boolean isVariableIncrementOrDecremented(
- @NotNull PsiVariable variable, @Nullable PsiStatement statement) {
- if (!(statement instanceof PsiExpressionStatement)) {
- return false;
- }
- final PsiExpressionStatement expressionStatement =
- (PsiExpressionStatement)statement;
- PsiExpression expression = expressionStatement.getExpression();
- expression = ParenthesesUtils.stripParentheses(expression);
- if (expression instanceof PsiPrefixExpression) {
- final PsiPrefixExpression prefixExpression =
- (PsiPrefixExpression)expression;
- final IElementType tokenType = prefixExpression.getOperationTokenType();
- if (!tokenType.equals(JavaTokenType.PLUSPLUS) &&
- !tokenType.equals(JavaTokenType.MINUSMINUS)) {
- return false;
- }
- final PsiExpression operand = prefixExpression.getOperand();
- return evaluatesToVariable(operand, variable);
- }
- else if (expression instanceof PsiPostfixExpression) {
- final PsiPostfixExpression postfixExpression =
- (PsiPostfixExpression)expression;
- final IElementType tokenType = postfixExpression.getOperationTokenType();
- if (!tokenType.equals(JavaTokenType.PLUSPLUS) &&
- !tokenType.equals(JavaTokenType.MINUSMINUS)) {
- return false;
- }
- final PsiExpression operand = postfixExpression.getOperand();
- return evaluatesToVariable(operand, variable);
- }
- else if (expression instanceof PsiAssignmentExpression) {
- final PsiAssignmentExpression assignmentExpression =
- (PsiAssignmentExpression)expression;
- final IElementType tokenType =
- assignmentExpression.getOperationTokenType();
- PsiExpression lhs = assignmentExpression.getLExpression();
- lhs = ParenthesesUtils.stripParentheses(lhs);
- if (!evaluatesToVariable(lhs, variable)) {
- return false;
- }
- PsiExpression rhs = assignmentExpression.getRExpression();
- rhs = ParenthesesUtils.stripParentheses(rhs);
- if (tokenType == JavaTokenType.EQ) {
- if (!(rhs instanceof PsiBinaryExpression)) {
- return false;
- }
- final PsiBinaryExpression binaryExpression =
- (PsiBinaryExpression)rhs;
- final IElementType token =
- binaryExpression.getOperationTokenType();
- if (!token.equals(JavaTokenType.PLUS) &&
- !token.equals(JavaTokenType.MINUS)) {
- return false;
- }
- PsiExpression lOperand = binaryExpression.getLOperand();
- lOperand = ParenthesesUtils.stripParentheses(lOperand);
- PsiExpression rOperand = binaryExpression.getROperand();
- rOperand = ParenthesesUtils.stripParentheses(rOperand);
- if (evaluatesToVariable(rOperand, variable)) {
- return true;
- }
- else if (evaluatesToVariable(lOperand, variable)) {
- return true;
- }
- }
- else if (tokenType == JavaTokenType.PLUSEQ ||
- tokenType == JavaTokenType.MINUSEQ) {
- return true;
- }
- }
- return false;
- }
-
- public static boolean evaluatesToVariable(
- @Nullable PsiExpression expression,
- @NotNull PsiVariable variable) {
- final PsiExpression strippedExpression =
- ParenthesesUtils.stripParentheses(expression);
- if (strippedExpression == null) {
- return false;
- }
- if (!(expression instanceof PsiReferenceExpression)) {
- return false;
- }
- final PsiReferenceExpression referenceExpression =
- (PsiReferenceExpression)expression;
- final PsiElement referent = referenceExpression.resolve();
- return variable.equals(referent);
- }
-
- public static boolean isAnyVariableAssigned(
- @NotNull Collection<PsiVariable> variables,
- @Nullable PsiElement context) {
- if (context == null) {
- return false;
- }
- final VariableAssignedVisitor visitor =
- new VariableAssignedVisitor(variables, true);
- context.accept(visitor);
- return visitor.isAssigned();
- }
-
- public static Set<PsiVariable> collectUsedVariables(
- PsiElement context) {
- if (context == null) {
- return Collections.emptySet();
- }
- final VariableCollectingVisitor visitor =
- new VariableCollectingVisitor();
- context.accept(visitor);
- return visitor.getUsedVariables();
- }
-
- private static class VariableCollectingVisitor
- extends JavaRecursiveElementVisitor {
-
- private final Set<PsiVariable> usedVariables = new HashSet();
-
- @Override
- public void visitReferenceExpression(
- PsiReferenceExpression expression) {
- super.visitReferenceExpression(expression);
- final PsiElement target = expression.resolve();
- if (!(target instanceof PsiVariable)) {
- return;
- }
- final PsiVariable variable = (PsiVariable)target;
- usedVariables.add(variable);
- }
-
- public Set<PsiVariable> getUsedVariables() {
- return usedVariables;
- }
- }
-}
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/VariableAssignedVisitor.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/VariableAssignedVisitor.java
deleted file mode 100644
index 8352febe9861..000000000000
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/VariableAssignedVisitor.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright 2003-2013 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.
- * 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.ipp.psiutils;
-
-import com.intellij.psi.*;
-import com.intellij.psi.tree.IElementType;
-import com.siyeh.ig.psiutils.ParenthesesUtils;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Collection;
-
-class VariableAssignedVisitor extends JavaRecursiveElementVisitor {
-
- @NotNull private final Collection<PsiVariable> variables;
- private final boolean recurseIntoClasses;
- private boolean assigned = false;
-
- public VariableAssignedVisitor(@NotNull Collection<PsiVariable> variables,
- boolean recurseIntoClasses) {
- this.variables = variables;
- this.recurseIntoClasses = recurseIntoClasses;
- }
-
- @Override
- public void visitElement(@NotNull PsiElement element) {
- if (assigned) {
- return;
- }
- super.visitElement(element);
- }
-
- @Override
- public void visitAssignmentExpression(
- @NotNull PsiAssignmentExpression assignment) {
- if (assigned) {
- return;
- }
- super.visitAssignmentExpression(assignment);
- final PsiExpression lhs = assignment.getLExpression();
- for (PsiVariable variable : variables) {
- if (mayEvaluateToVariable(lhs, variable)) {
- assigned = true;
- }
- }
- }
-
- @Override
- public void visitClass(PsiClass aClass) {
- if (!recurseIntoClasses) {
- return;
- }
- if (assigned) {
- return;
- }
- super.visitClass(aClass);
- }
-
- @Override
- public void visitPrefixExpression(
- @NotNull PsiPrefixExpression prefixExpression) {
- if (assigned) {
- return;
- }
- super.visitPrefixExpression(prefixExpression);
- final IElementType tokenType = prefixExpression.getOperationTokenType();
- if (!tokenType.equals(JavaTokenType.PLUSPLUS) &&
- !tokenType.equals(JavaTokenType.MINUSMINUS)) {
- return;
- }
- final PsiExpression operand = prefixExpression.getOperand();
- for (PsiVariable variable : variables) {
- if (mayEvaluateToVariable(operand, variable)) {
- assigned = true;
- }
- }
- }
-
- @Override
- public void visitPostfixExpression(
- @NotNull PsiPostfixExpression postfixExpression) {
- if (assigned) {
- return;
- }
- super.visitPostfixExpression(postfixExpression);
- final IElementType tokenType = postfixExpression.getOperationTokenType();
- if (!tokenType.equals(JavaTokenType.PLUSPLUS) &&
- !tokenType.equals(JavaTokenType.MINUSMINUS)) {
- return;
- }
- final PsiExpression operand = postfixExpression.getOperand();
- for (PsiVariable variable : variables) {
- if (mayEvaluateToVariable(operand, variable)) {
- assigned = true;
- }
- }
- }
-
- public static boolean mayEvaluateToVariable(
- @Nullable PsiExpression expression,
- @NotNull PsiVariable variable) {
- if (expression == null) {
- return false;
- }
- if (expression instanceof PsiBinaryExpression) {
- final PsiBinaryExpression binaryExpression =
- (PsiBinaryExpression)expression;
- final PsiExpression lOperand = binaryExpression.getLOperand();
- final PsiExpression rOperand = binaryExpression.getROperand();
- return mayEvaluateToVariable(lOperand, variable) ||
- mayEvaluateToVariable(rOperand, variable);
- }
- if (expression instanceof PsiParenthesizedExpression) {
- final PsiParenthesizedExpression parenthesizedExpression =
- (PsiParenthesizedExpression)expression;
- final PsiExpression containedExpression =
- parenthesizedExpression.getExpression();
- return mayEvaluateToVariable(containedExpression, variable);
- }
- if (expression instanceof PsiTypeCastExpression) {
- final PsiTypeCastExpression typeCastExpression =
- (PsiTypeCastExpression)expression;
- final PsiExpression containedExpression =
- typeCastExpression.getOperand();
- return mayEvaluateToVariable(containedExpression, variable);
- }
- if (expression instanceof PsiConditionalExpression) {
- final PsiConditionalExpression conditional =
- (PsiConditionalExpression)expression;
- final PsiExpression thenExpression = conditional.getThenExpression();
- final PsiExpression elseExpression = conditional.getElseExpression();
- return mayEvaluateToVariable(thenExpression, variable) ||
- mayEvaluateToVariable(elseExpression, variable);
- }
- if (expression instanceof PsiArrayAccessExpression) {
- final PsiElement parent = expression.getParent();
- if (parent instanceof PsiArrayAccessExpression) {
- return false;
- }
- final PsiType type = variable.getType();
- if (!(type instanceof PsiArrayType)) {
- return false;
- }
- final PsiArrayType arrayType = (PsiArrayType)type;
- final int dimensions = arrayType.getArrayDimensions();
- if (dimensions <= 1) {
- return false;
- }
- PsiArrayAccessExpression arrayAccessExpression =
- (PsiArrayAccessExpression)expression;
- PsiExpression arrayExpression =
- arrayAccessExpression.getArrayExpression();
- int count = 1;
- while (arrayExpression instanceof PsiArrayAccessExpression) {
- arrayAccessExpression =
- (PsiArrayAccessExpression)arrayExpression;
- arrayExpression = arrayAccessExpression.getArrayExpression();
- count++;
- }
- return count != dimensions &&
- mayEvaluateToVariable(arrayExpression, variable);
- }
- return evaluatesToVariable(expression, variable);
- }
-
- public static boolean evaluatesToVariable(
- @Nullable PsiExpression expression,
- @NotNull PsiVariable variable) {
- final PsiExpression strippedExpression =
- ParenthesesUtils.stripParentheses(expression);
- if (strippedExpression == null) {
- return false;
- }
- if (!(expression instanceof PsiReferenceExpression)) {
- return false;
- }
- final PsiReferenceExpression referenceExpression =
- (PsiReferenceExpression)expression;
- final PsiElement referent = referenceExpression.resolve();
- return variable.equals(referent);
- }
-
- public boolean isAssigned() {
- return assigned;
- }
-} \ No newline at end of file
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/ReplaceIfWithSwitchIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/ReplaceIfWithSwitchIntention.java
index cde03e1aeb1c..9f40b4b36a13 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/ReplaceIfWithSwitchIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/switchtoif/ReplaceIfWithSwitchIntention.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.
@@ -18,12 +18,12 @@ package com.siyeh.ipp.switchtoif;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
+import com.siyeh.ig.psiutils.ControlFlowUtils;
import com.siyeh.ig.psiutils.EquivalenceChecker;
import com.siyeh.ig.psiutils.SwitchUtils;
import com.siyeh.ig.psiutils.SwitchUtils.IfStatementBranch;
import com.siyeh.ipp.base.Intention;
import com.siyeh.ipp.base.PsiElementPredicate;
-import com.siyeh.ipp.psiutils.ControlFlowUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/MergeIfOrPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/MergeIfOrPredicate.java
index b2c5aa87a3fb..3dfd039fec5c 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/MergeIfOrPredicate.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/MergeIfOrPredicate.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2012 Dave Griffith
+ * 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,9 +17,9 @@ package com.siyeh.ipp.trivialif;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
+import com.siyeh.ig.psiutils.ControlFlowUtils;
import com.siyeh.ig.psiutils.EquivalenceChecker;
import com.siyeh.ipp.base.PsiElementPredicate;
-import com.siyeh.ipp.psiutils.ControlFlowUtils;
import com.siyeh.ipp.psiutils.ErrorUtil;
class MergeIfOrPredicate implements PsiElementPredicate {
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/MergeParallelIfsPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/MergeParallelIfsPredicate.java
index f2e889316400..57a78912c100 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/MergeParallelIfsPredicate.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/MergeParallelIfsPredicate.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.
@@ -17,11 +17,11 @@ package com.siyeh.ipp.trivialif;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
+import com.siyeh.ig.psiutils.ControlFlowUtils;
import com.siyeh.ig.psiutils.EquivalenceChecker;
+import com.siyeh.ig.psiutils.VariableAccessUtils;
import com.siyeh.ipp.base.PsiElementPredicate;
-import com.siyeh.ipp.psiutils.ControlFlowUtils;
import com.siyeh.ipp.psiutils.ErrorUtil;
-import com.siyeh.ipp.psiutils.VariableAccessUtils;
import java.util.Collection;
import java.util.HashSet;
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/BetweenIfAndElse.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/BetweenIfAndElse.java
new file mode 100644
index 000000000000..00658098d56d
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/BetweenIfAndElse.java
@@ -0,0 +1,10 @@
+class X {
+ {
+ if (true) {
+ System.out.println();
+ }
+<caret> else {
+ System.out.println();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse.java
new file mode 100644
index 000000000000..29a595804f5c
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse.java
@@ -0,0 +1,10 @@
+class X {
+ {
+ if (true) {
+ System.out.println();
+ }<caret>
+ else {
+ System.out.println();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse2.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse2.java
new file mode 100644
index 000000000000..9815cdf830e4
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse2.java
@@ -0,0 +1,10 @@
+class X {
+ {
+ if<caret> (true) {
+ System.out.println();
+ }
+ else {
+ System.out.println();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse2_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse2_after.java
new file mode 100644
index 000000000000..feae02671942
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse2_after.java
@@ -0,0 +1,8 @@
+class X {
+ {
+ if (true) System.out.println();
+ else {
+ System.out.println();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse_after.java
new file mode 100644
index 000000000000..feae02671942
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/remove/IfElse_after.java
@@ -0,0 +1,8 @@
+class X {
+ {
+ if (true) System.out.println();
+ else {
+ System.out.println();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/braces/RemoveBracesIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/braces/RemoveBracesIntentionTest.java
new file mode 100644
index 000000000000..74ebd04fe402
--- /dev/null
+++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/braces/RemoveBracesIntentionTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.ipp.braces;
+
+import com.siyeh.IntentionPowerPackBundle;
+import com.siyeh.ipp.IPPTestCase;
+
+/**
+ * @see RemoveBracesIntention
+ * @author Bas Leijdekkers
+ */
+public class RemoveBracesIntentionTest extends IPPTestCase {
+ @Override
+ protected String getRelativePath() {
+ return "braces/remove";
+ }
+
+ @Override
+ protected String getIntentionName() {
+ return IntentionPowerPackBundle.message("remove.braces.intention.name", "if");
+ }
+
+ public void testBetweenIfAndElse() { assertIntentionNotAvailable(RemoveBracesIntention.class);}
+ public void testIfElse() { doTest(); }
+ public void testIfElse2() { doTest(); }
+}
diff --git a/plugins/ant/jps-plugin/ant-jps-plugin.iml b/plugins/ant/jps-plugin/ant-jps-plugin.iml
index 976f684d067a..12aeb835539a 100644
--- a/plugins/ant/jps-plugin/ant-jps-plugin.iml
+++ b/plugins/ant/jps-plugin/ant-jps-plugin.iml
@@ -13,6 +13,7 @@
<orderEntry type="module" module-name="util" />
<orderEntry type="module" module-name="jps-builders" />
<orderEntry type="module" module-name="java-runtime" />
+ <orderEntry type="module" module-name="jps-serialization-tests" scope="TEST" />
</component>
</module>
diff --git a/plugins/ant/src/com/intellij/lang/ant/AntImportsIndex.java b/plugins/ant/src/com/intellij/lang/ant/AntImportsIndex.java
index be3dc676245b..6c8e413fae95 100644
--- a/plugins/ant/src/com/intellij/lang/ant/AntImportsIndex.java
+++ b/plugins/ant/src/com/intellij/lang/ant/AntImportsIndex.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.
@@ -98,11 +98,13 @@ public class AntImportsIndex extends ScalarIndexExtension<Integer>{
return DATA_INDEXER;
}
+ @NotNull
@Override
public KeyDescriptor<Integer> getKeyDescriptor() {
return EnumeratorIntegerDescriptor.INSTANCE;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new DefaultFileTypeSpecificInputFilter(StdFileTypes.XML);
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 89385066f85a..15ce261fa653 100644
--- a/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/CvsBundle.properties
+++ b/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/CvsBundle.properties
@@ -415,7 +415,6 @@ action.Cvs.ToggleOffline.text=_Work Offline
action.Cvs.ToggleOffline.description=Toggle offline mode for CVS root containing selected file
set.online.notification.text=Set to online mode
set.offline.notification.text=Set to offline mode
-plugin.CVS.description=Provides integration with CVS version control system
adding.cvsignore.files.to.cvs.action.name=Adding .cvsignore Files to CVS
browse.repository.operation.name=Browse Repository
configure.global.cvs.settings.action.name=Configure Global CVS Settings
diff --git a/plugins/cvs/cvs-plugin/src/META-INF/plugin.xml b/plugins/cvs/cvs-plugin/src/META-INF/plugin.xml
index 20f34c5513b0..1cefc9748ae4 100644
--- a/plugins/cvs/cvs-plugin/src/META-INF/plugin.xml
+++ b/plugins/cvs/cvs-plugin/src/META-INF/plugin.xml
@@ -5,6 +5,17 @@
<vendor>JetBrains</vendor>
<resource-bundle>com.intellij.cvsSupport2.CvsBundle</resource-bundle>
<category>VCS Integration</category>
+ <description>
+ <![CDATA[
+ Allows working with CVS version control system.
+ The following features are available:
+ <ul>
+ <li>Dedicated page under the Version Control node in the Settings/Preferences dialog.</li>
+ <li>When CVS is not enabled, it is still possible to browse, check out sources from and import into the available CVS repositories.</li>
+ <li>When CVS is enabled, the CVS node appears on the VCS menu, and on the context menu of the editor.
+ </ul>
+ ]]>
+ </description>
<depends>com.intellij.modules.lang</depends>
<depends>com.intellij.modules.vcs</depends>
diff --git a/plugins/devkit/jps-plugin/devkit-jps-plugin.iml b/plugins/devkit/jps-plugin/devkit-jps-plugin.iml
index f88b075e0722..a80f7f38f339 100644
--- a/plugins/devkit/jps-plugin/devkit-jps-plugin.iml
+++ b/plugins/devkit/jps-plugin/devkit-jps-plugin.iml
@@ -12,6 +12,7 @@
<orderEntry type="module" module-name="jps-model-serialization" />
<orderEntry type="module" module-name="jps-builders" />
<orderEntry type="module" module-name="jps-model-impl" scope="TEST" />
+ <orderEntry type="module" module-name="jps-serialization-tests" scope="TEST" />
</component>
</module>
diff --git a/plugins/devkit/src/references/IconsReferencesContributor.java b/plugins/devkit/src/references/IconsReferencesContributor.java
index 74d258783660..eac85d8f0f3c 100644
--- a/plugins/devkit/src/references/IconsReferencesContributor.java
+++ b/plugins/devkit/src/references/IconsReferencesContributor.java
@@ -299,7 +299,7 @@ public class IconsReferencesContributor extends PsiReferenceContributor implemen
model.setCaseSensitive(true);
model.setFindAll(true);
model.setWholeWordsOnly(true);
- FindInProjectUtil.findUsages(model, FindInProjectUtil.getPsiDirectory(model, project), project, false, new Processor<UsageInfo>() {
+ FindInProjectUtil.findUsages(model, FindInProjectUtil.getPsiDirectory(model, project), project, new Processor<UsageInfo>() {
@Override
public boolean process(final UsageInfo usage) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
diff --git a/plugins/eclipse/resources/META-INF/plugin.xml b/plugins/eclipse/resources/META-INF/plugin.xml
index b3cd54debe52..a3f76504c14c 100644
--- a/plugins/eclipse/resources/META-INF/plugin.xml
+++ b/plugins/eclipse/resources/META-INF/plugin.xml
@@ -1,7 +1,20 @@
<idea-plugin>
<name>Eclipse Integration</name>
<id>org.jetbrains.idea.eclipse</id>
- <description>Provides possibility to import, export and synchronize Eclipse project files</description>
+ <description>
+ <![CDATA[
+ This plugin enables integration with Eclipse and provides the following features:
+ <ul>
+ <li>Open Eclipse project in IntelliJ IDEA</li>
+ <li>Import Eclipse project into IntelliJ IDEA</li>
+ <li>Export IntelliJ IDEA project into Eclipse</li>
+ <li>Convert IntelliJ IDEA module to Eclipse-compatible format</li>
+ <li>Synchronize Eclipse project files</li>
+ </ul>
+ <p/>
+ ]]>
+ </description>
+
<version>3.0</version>
<vendor url="http://www.jetbrains.com" logo="/general/ijLogo.png">JetBrains s.r.o.</vendor>
<extensions defaultExtensionNs="com.intellij">
diff --git a/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentChecker.java b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentChecker.java
index 155e7e2e2b78..df40458aa36b 100644
--- a/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentChecker.java
+++ b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentChecker.java
@@ -16,7 +16,6 @@
package com.intellij.remoteServer.util;
import com.intellij.execution.configurations.RuntimeConfigurationWarning;
-import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
@@ -29,14 +28,11 @@ import com.intellij.remoteServer.configuration.ServerConfigurationBase;
import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
import com.intellij.remoteServer.configuration.deployment.ModuleDeploymentSource;
import git4idea.GitUtil;
-import git4idea.commands.Git;
-import git4idea.repo.GitRemote;
import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
import java.io.File;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.List;
/**
* @author michael.golubev
@@ -47,21 +43,23 @@ public class CloudGitDeploymentChecker<
SR extends CloudMultiSourceServerRuntimeInstance<T, ?, ?, ?>> {
private GitRepositoryManager myGitRepositoryManager;
- private Git myGit;
private final DeploymentSource myDeploymentSource;
private final RemoteServer<SC> myServer;
private final CloudDeploymentNameEditor<T> mySettingsEditor;
+ private final CloudGitDeploymentDetector myDetector;
public CloudGitDeploymentChecker(DeploymentSource deploymentSource,
RemoteServer<SC> server,
- CloudDeploymentNameEditor<T> settingsEditor) {
+ CloudDeploymentNameEditor<T> settingsEditor,
+ CloudGitDeploymentDetector detector) {
myDeploymentSource = deploymentSource;
myServer = server;
mySettingsEditor = settingsEditor;
+ myDetector = detector;
}
- public void checkGitUrl(final T settings, Pattern gitUrlPattern) throws ConfigurationException {
+ public void checkGitUrl(final T settings) throws ConfigurationException {
if (!(myDeploymentSource instanceof ModuleDeploymentSource)) {
return;
}
@@ -82,12 +80,6 @@ public class CloudGitDeploymentChecker<
if (myGitRepositoryManager == null) {
myGitRepositoryManager = GitUtil.getRepositoryManager(project);
}
- if (myGit == null) {
- myGit = ServiceManager.getService(Git.class);
- if (myGit == null) {
- return;
- }
- }
VirtualFile contentRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(contentRootFile);
if (contentRoot == null) {
@@ -102,28 +94,11 @@ public class CloudGitDeploymentChecker<
String expectedName = settings.getDeploymentSourceName(myDeploymentSource);
- boolean unexpectedNameFound = false;
- for (GitRemote remote : repository.getRemotes()) {
- for (String url : remote.getUrls()) {
- Matcher matcher = gitUrlPattern.matcher(url);
- if (matcher.matches()) {
- String matchedName = matcher.group(1);
- if (matchedName.equals(expectedName)) {
- return;
- }
- else {
- unexpectedNameFound = true;
- break;
- }
- }
- }
- }
-
- if (!unexpectedNameFound) {
+ List<String> appNames = myDetector.collectApplicationNames(repository);
+ if (appNames.isEmpty() || appNames.contains(expectedName)) {
return;
}
-
RuntimeConfigurationWarning warning =
new RuntimeConfigurationWarning("Cloud Git URL found in repository, but it doesn't match the run configuration");
diff --git a/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentDetector.java b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentDetector.java
new file mode 100644
index 000000000000..f4fdd3fc5ae8
--- /dev/null
+++ b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentDetector.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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 git4idea.repo.GitRemote;
+import git4idea.repo.GitRepository;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author michael.golubev
+ */
+public class CloudGitDeploymentDetector {
+
+ private final Pattern myGitUrlPattern;
+
+ public CloudGitDeploymentDetector(Pattern gitUrlPattern) {
+ myGitUrlPattern = gitUrlPattern;
+ }
+
+ public List<String> collectApplicationNames(@NotNull GitRepository repository) {
+ List<String> result = new ArrayList<String>();
+ for (GitRemote remote : repository.getRemotes()) {
+ for (String url : remote.getUrls()) {
+ Matcher matcher = myGitUrlPattern.matcher(url);
+ if (matcher.matches()) {
+ result.add(matcher.group(1));
+ }
+ }
+ }
+ return result;
+ }
+}
diff --git a/plugins/git4idea/src/META-INF/plugin.xml b/plugins/git4idea/src/META-INF/plugin.xml
index 5bd07d3b8883..8664c8ae51e2 100644
--- a/plugins/git4idea/src/META-INF/plugin.xml
+++ b/plugins/git4idea/src/META-INF/plugin.xml
@@ -1,7 +1,18 @@
<idea-plugin>
<name>Git Integration</name>
<id>Git4Idea</id>
- <description>Provides integration with Git version control system</description>
+ <description>
+ <![CDATA[
+ Allows working with <a href="http://git-scm.com/">Git version control system</a>.
+ The following features are available:
+ <ul>
+ <li>Dedicated page under the Version Control node in the Settings/Preferences dialog.</li>
+ <li>Ability to browse, check out sources from and import into the available Git repositories, when Git is not enabled.</li>
+ <li>When Git is enabled, the Git node appears on the VCS menu, and on the context menu of the editor.</li>
+ </ul>
+ <p>Numerous plugins depend on the Git Integration plugin.</p>
+ ]]>
+ </description>
<version>8.1</version>
<category>VCS Integration</category>
<vendor url="http://svn.jetbrains.org/idea/Trunk/bundled/git4idea/" logo="/general/ijLogo.png">JetBrains</vendor>
diff --git a/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java b/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java
index d5c4b3fa8505..013d4cafe836 100644
--- a/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java
+++ b/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java
@@ -25,7 +25,10 @@ import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vcs.*;
+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;
import com.intellij.openapi.vcs.checkin.CheckinChangeListSpecificComponent;
@@ -33,7 +36,10 @@ import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.GuiUtils;
-import com.intellij.util.*;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.FunctionUtil;
+import com.intellij.util.NullableFunction;
+import com.intellij.util.PairConsumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.UIUtil;
@@ -643,8 +649,8 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
@Override
@NotNull
- protected Set<VirtualFile> getRoots() {
- return GitUtil.gitRoots(getSelectedFilePaths());
+ protected Set<VirtualFile> getVcsRoots(@NotNull Collection<FilePath> filePaths) {
+ return GitUtil.gitRoots(filePaths);
}
@Nullable
@@ -665,26 +671,18 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
return h.run();
}
- @NotNull
- private List<FilePath> getSelectedFilePaths() {
- return ContainerUtil.map(myCheckinPanel.getFiles(), new Function<File, FilePath>() {
- @Override
- public FilePath fun(File file) {
- return new FilePathImpl(file, file.isDirectory());
- }
- });
- }
-
private List<String> getUsersList(final Project project) {
return NewGitUsersComponent.getInstance(project).get();
}
+ @Override
public void refresh() {
super.refresh();
myAuthor.setSelectedItem("");
reset();
}
+ @Override
public void saveState() {
String author = (String)myAuthor.getEditor().getItem();
myNextCommitAuthor = author.length() == 0 ? null : author;
@@ -699,6 +697,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
myNextCommitAuthorDate = myAuthorDate;
}
+ @Override
public void restoreState() {
refresh();
}
diff --git a/plugins/git4idea/src/git4idea/history/NewGitUsersComponent.java b/plugins/git4idea/src/git4idea/history/NewGitUsersComponent.java
index 2afb3c821223..89ccaa51d195 100644
--- a/plugins/git4idea/src/git4idea/history/NewGitUsersComponent.java
+++ b/plugins/git4idea/src/git4idea/history/NewGitUsersComponent.java
@@ -1,9 +1,12 @@
/*
- * 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.
* 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.
@@ -88,7 +91,7 @@ public class NewGitUsersComponent {
private static class MyDataExternalizer implements DataExternalizer<List<String>> {
@Override
- public List<String> read(DataInput in) throws IOException {
+ public List<String> read(@NotNull DataInput in) throws IOException {
final int size = in.readInt();
final ArrayList<String> result = new ArrayList<String>(size);
for (int i = 0; i < size; i++) {
@@ -98,7 +101,7 @@ public class NewGitUsersComponent {
}
@Override
- public void save(DataOutput out, List<String> value) throws IOException {
+ public void save(@NotNull DataOutput out, List<String> value) throws IOException {
out.writeInt(value.size());
for (String s : value) {
out.writeUTF(s);
diff --git a/plugins/git4idea/src/git4idea/history/wholeTree/GitCommitsSequentialIndex.java b/plugins/git4idea/src/git4idea/history/wholeTree/GitCommitsSequentialIndex.java
index 70239c1b1a5d..0c69e45f6ae2 100644
--- a/plugins/git4idea/src/git4idea/history/wholeTree/GitCommitsSequentialIndex.java
+++ b/plugins/git4idea/src/git4idea/history/wholeTree/GitCommitsSequentialIndex.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.
@@ -39,6 +39,7 @@ import com.intellij.util.io.EnumeratorStringDescriptor;
import git4idea.GitRevisionNumber;
import git4idea.history.GitHistoryUtils;
import git4idea.history.browser.SHAHash;
+import org.jetbrains.annotations.NotNull;
import java.io.*;
import java.util.*;
@@ -120,12 +121,12 @@ public class GitCommitsSequentialIndex implements GitCommitsSequentially {
private DataExternalizer<String> createExternalizer() {
return new DataExternalizer<String>() {
@Override
- public void save(DataOutput out, String value) throws IOException {
+ public void save(@NotNull DataOutput out, String value) throws IOException {
out.writeUTF(value);
}
@Override
- public String read(DataInput in) throws IOException {
+ public String read(@NotNull DataInput in) throws IOException {
return in.readUTF();
}
};
diff --git a/plugins/git4idea/tests/git4idea/tests/SkeletonBuilderTest.java b/plugins/git4idea/tests/git4idea/tests/SkeletonBuilderTest.java
index aabf48c54fad..1417a118eacc 100644
--- a/plugins/git4idea/tests/git4idea/tests/SkeletonBuilderTest.java
+++ b/plugins/git4idea/tests/git4idea/tests/SkeletonBuilderTest.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.
@@ -789,6 +789,7 @@ public class SkeletonBuilderTest extends TestCase {
return new MockVirtualFileSystem();
}
+ @NotNull
@Override
public String getPath() {
return "mock";
diff --git a/plugins/github/src/META-INF/plugin.xml b/plugins/github/src/META-INF/plugin.xml
index e0345633a81d..8baf48bf6eee 100644
--- a/plugins/github/src/META-INF/plugin.xml
+++ b/plugins/github/src/META-INF/plugin.xml
@@ -2,7 +2,17 @@
<name>GitHub</name>
<id>org.jetbrains.plugins.github</id>
<vendor>JetBrains</vendor>
- <description>GitHub integration</description>
+ <description>
+ <![CDATA[
+ Allows working with <a href="http://github.com/">GitHub</a>.
+ The following features are available:
+ <ul>
+ <li>Dedicated page under the Version Control node in the Settings/Preferences dialog.</li>
+ <li>Ability to browse, check out sources from and import into the available Git repositories, when GitHub is not enabled.</li>
+ <li>When GitHub is enabled, the GitHub node appears on the VCS menu, and on the context menu of the editor.
+ </ul>
+ ]]>
+ </description>
<depends>com.intellij.modules.lang</depends>
<depends>Git4Idea</depends>
diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java
index 878b9b855a0c..600f484f0c0b 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vfs.VirtualFile;
@@ -41,12 +42,14 @@ import org.jetbrains.plugins.github.api.GithubGist;
import org.jetbrains.plugins.github.exceptions.GithubOperationCanceledException;
import org.jetbrains.plugins.github.ui.GithubCreateGistDialog;
import org.jetbrains.plugins.github.util.GithubAuthData;
+import org.jetbrains.plugins.github.util.GithubAuthDataHolder;
import org.jetbrains.plugins.github.util.GithubNotifications;
import org.jetbrains.plugins.github.util.GithubUtil;
import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.atomic.AtomicReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import static org.jetbrains.plugins.github.api.GithubGist.FileContent;
@@ -110,33 +113,24 @@ public class GithubCreateGistAction extends DumbAwareAction {
return;
}
- GithubAuthData auth = GithubAuthData.createAnonymous();
- if (!dialog.isAnonymous()) {
- try {
- auth = getValidAuthData(project);
- }
- catch (GithubOperationCanceledException e) {
- return;
- }
- catch (IOException e) {
- GithubNotifications.showError(project, "Can't create gist", e);
- return;
- }
+ final GithubAuthDataHolder authHolder = getValidAuthData(project, dialog.isAnonymous());
+ if (authHolder == null) {
+ return;
}
- final AtomicReference<String> url = new AtomicReference<String>();
- final GithubAuthData finalAuth = auth;
+ final Ref<String> url = new Ref<String>();
new Task.Backgroundable(project, "Creating Gist...") {
@Override
public void run(@NotNull ProgressIndicator indicator) {
List<FileContent> contents = collectContents(project, editor, file, files);
- String gistUrl = createGist(project, finalAuth, contents, dialog.isPrivate(), dialog.getDescription(), dialog.getFileName());
+ String gistUrl =
+ createGist(project, authHolder, indicator, contents, dialog.isPrivate(), dialog.getDescription(), dialog.getFileName());
url.set(gistUrl);
}
@Override
public void onSuccess() {
- if (url.get() == null) {
+ if (url.isNull()) {
return;
}
if (dialog.isOpenInBrowser()) {
@@ -149,17 +143,32 @@ public class GithubCreateGistAction extends DumbAwareAction {
}.queue();
}
- @NotNull
- private static GithubAuthData getValidAuthData(@NotNull final Project project) throws IOException {
- return GithubUtil.computeValueInModal(project, "Access to GitHub",
- new ThrowableConvertor<ProgressIndicator, GithubAuthData, IOException>() {
- @NotNull
- @Override
- public GithubAuthData convert(ProgressIndicator indicator) throws IOException {
- return GithubUtil.getValidAuthDataFromConfig(project, indicator);
- }
- }
- );
+ @Nullable
+ private static GithubAuthDataHolder getValidAuthData(@NotNull final Project project, boolean isAnonymous) {
+ if (isAnonymous) {
+ return new GithubAuthDataHolder(GithubAuthData.createAnonymous());
+ }
+ else {
+ try {
+ return GithubUtil
+ .computeValueInModal(project, "Access to GitHub", new ThrowableConvertor<ProgressIndicator, GithubAuthDataHolder, IOException>() {
+ @NotNull
+ @Override
+ public GithubAuthDataHolder convert(ProgressIndicator indicator) throws IOException {
+ return GithubUtil.getValidAuthDataHolderFromConfig(project, indicator);
+ }
+ }
+ );
+ }
+ catch (GithubOperationCanceledException e) {
+ return null;
+ }
+ catch (IOException e) {
+ GithubNotifications.showError(project, "Can't create gist", e);
+ return null;
+ }
+
+ }
}
@NotNull
@@ -197,10 +206,11 @@ public class GithubCreateGistAction extends DumbAwareAction {
@Nullable
static String createGist(@NotNull Project project,
- @NotNull GithubAuthData auth,
+ @NotNull GithubAuthDataHolder auth,
+ @NotNull ProgressIndicator indicator,
@NotNull List<FileContent> contents,
- boolean isPrivate,
- @NotNull String description,
+ final boolean isPrivate,
+ @NotNull final String description,
@Nullable String filename) {
if (contents.isEmpty()) {
GithubNotifications.showWarning(project, FAILED_TO_CREATE_GIST, "Can't create empty gist");
@@ -211,8 +221,14 @@ public class GithubCreateGistAction extends DumbAwareAction {
contents = Collections.singletonList(new FileContent(filename, entry.getContent()));
}
try {
- GithubGist gist = GithubApiUtil.createGist(auth, contents, description, isPrivate);
- return gist.getHtmlUrl();
+ final List<FileContent> finalContents = contents;
+ return GithubUtil.runTask(project, auth, indicator, new ThrowableConvertor<GithubAuthData, GithubGist, IOException>() {
+ @NotNull
+ @Override
+ public GithubGist convert(@NotNull GithubAuthData auth) throws IOException {
+ return GithubApiUtil.createGist(auth, finalContents, description, isPrivate);
+ }
+ }).getHtmlUrl();
}
catch (IOException e) {
GithubNotifications.showError(project, FAILED_TO_CREATE_GIST, e);
diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestWorker.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestWorker.java
index ee357b145601..d06851c89b97 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestWorker.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestWorker.java
@@ -8,6 +8,7 @@ import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.Change;
@@ -37,17 +38,13 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.api.*;
import org.jetbrains.plugins.github.exceptions.GithubOperationCanceledException;
import org.jetbrains.plugins.github.ui.GithubSelectForkDialog;
-import org.jetbrains.plugins.github.util.GithubAuthData;
-import org.jetbrains.plugins.github.util.GithubNotifications;
-import org.jetbrains.plugins.github.util.GithubUrlUtil;
-import org.jetbrains.plugins.github.util.GithubUtil;
+import org.jetbrains.plugins.github.util.*;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
-import java.util.concurrent.atomic.AtomicReference;
/**
* @author Aleksey Pivovarov
@@ -63,7 +60,7 @@ public class GithubCreatePullRequestWorker {
@NotNull private final String myRemoteName;
@NotNull private final String myRemoteUrl;
@NotNull private final String myCurrentBranch;
- @NotNull private final GithubAuthData myAuth;
+ @NotNull private final GithubAuthDataHolder myAuthHolder;
@NotNull private final Map<String, FutureTask<DiffInfo>> myDiffInfos;
@@ -77,7 +74,7 @@ public class GithubCreatePullRequestWorker {
@NotNull String remoteName,
@NotNull String remoteUrl,
@NotNull String currentBranch,
- @NotNull GithubAuthData auth) {
+ @NotNull GithubAuthDataHolder authHolder) {
myProject = project;
myGit = git;
myGitRepository = gitRepository;
@@ -85,7 +82,7 @@ public class GithubCreatePullRequestWorker {
myRemoteName = remoteName;
myRemoteUrl = remoteUrl;
myCurrentBranch = currentBranch;
- myAuth = auth;
+ myAuthHolder = authHolder;
myDiffInfos = new HashMap<String, FutureTask<DiffInfo>>();
}
@@ -134,14 +131,14 @@ public class GithubCreatePullRequestWorker {
return null;
}
- GithubAuthData auth;
+ GithubAuthDataHolder authHolder;
try {
- auth = GithubUtil
- .computeValueInModal(project, "Access to GitHub", new ThrowableConvertor<ProgressIndicator, GithubAuthData, IOException>() {
+ authHolder = GithubUtil
+ .computeValueInModal(project, "Access to GitHub", new ThrowableConvertor<ProgressIndicator, GithubAuthDataHolder, IOException>() {
@NotNull
@Override
- public GithubAuthData convert(ProgressIndicator indicator) throws IOException {
- return GithubUtil.getValidAuthDataFromConfig(project, indicator);
+ public GithubAuthDataHolder convert(ProgressIndicator indicator) throws IOException {
+ return GithubUtil.getValidAuthDataHolderFromConfig(project, indicator);
}
});
}
@@ -153,7 +150,7 @@ public class GithubCreatePullRequestWorker {
return null;
}
- return new GithubCreatePullRequestWorker(project, git, gitRepository, path, remoteName, remoteUrl, currentBranch.getName(), auth);
+ return new GithubCreatePullRequestWorker(project, git, gitRepository, path, remoteName, remoteUrl, currentBranch.getName(), authHolder);
}
@Nullable
@@ -168,7 +165,7 @@ public class GithubCreatePullRequestWorker {
GitRemote targetRemote = GithubUtil.findGithubRemote(myGitRepository, forkPath);
String targetRemoteName = targetRemote == null ? null : targetRemote.getName();
if (targetRemoteName == null) {
- final AtomicReference<Integer> responseRef = new AtomicReference<Integer>();
+ final Ref<Integer> responseRef = new Ref<Integer>();
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
@@ -182,13 +179,21 @@ public class GithubCreatePullRequestWorker {
}
// load available branches
- List<String> branches = ContainerUtil.map(GithubApiUtil.getRepoBranches(myAuth, forkPath.getUser(), forkPath.getRepository()),
- new Function<GithubBranch, String>() {
- @Override
- public String fun(GithubBranch githubBranch) {
- return githubBranch.getName();
- }
- });
+ List<String> branches = ContainerUtil.map(GithubUtil.runTask(myProject, myAuthHolder, indicator,
+ new ThrowableConvertor<GithubAuthData, List<GithubBranch>, IOException>() {
+ @Override
+ public List<GithubBranch> convert(@NotNull GithubAuthData auth)
+ throws IOException {
+ return GithubApiUtil.getRepoBranches(auth, forkPath.getUser(),
+ forkPath.getRepository());
+ }
+ }
+ ), new Function<GithubBranch, String>() {
+ @Override
+ public String fun(GithubBranch githubBranch) {
+ return githubBranch.getName();
+ }
+ });
// fetch
if (targetRemoteName != null) {
@@ -251,7 +256,7 @@ public class GithubCreatePullRequestWorker {
@Nullable
public GithubFullPath showTargetDialog(boolean firstTime) {
- final GithubInfo2 info = getAvailableForksInModal(myProject, myGitRepository, myAuth, myPath);
+ final GithubInfo2 info = getAvailableForksInModal(myProject, myGitRepository, myAuthHolder, myPath);
if (info == null) {
return null;
}
@@ -281,8 +286,8 @@ public class GithubCreatePullRequestWorker {
return GithubUtil.computeValueInModal(myProject, "Access to GitHub", new Convertor<ProgressIndicator, GithubFullPath>() {
@Nullable
@Override
- public GithubFullPath convert(ProgressIndicator o) {
- return findRepositoryByUser(myProject, user, info.getForks(), myAuth, info.getSource());
+ public GithubFullPath convert(ProgressIndicator indicator) {
+ return findRepositoryByUser(myProject, myAuthHolder, indicator, user, info.getForks(), info.getSource());
}
});
}
@@ -301,8 +306,11 @@ public class GithubCreatePullRequestWorker {
return true;
}
if (info.getInfo().getBranchToHeadCommits(myGitRepository).isEmpty()) {
- GithubNotifications.showWarningDialog(myProject, CANNOT_CREATE_PULL_REQUEST,
- "Can't create empty pull request: the branch" + getCurrentBranch() + " in fully merged to the branch " + targetBranch + ".");
+ GithubNotifications.showWarningDialog(myProject, CANNOT_CREATE_PULL_REQUEST, "Can't create empty pull request: the branch" +
+ getCurrentBranch() +
+ " in fully merged to the branch " +
+ targetBranch +
+ ".");
return false;
}
if (info.getInfo().getHeadToBranchCommits(myGitRepository).isEmpty()) {
@@ -332,7 +340,8 @@ public class GithubCreatePullRequestWorker {
LOG.info("Creating pull request");
indicator.setText("Creating pull request...");
- GithubPullRequest request = createPullRequest(project, myAuth, myForkPath, title, description, headBranch, targetBranch);
+ GithubPullRequest request =
+ createPullRequest(project, myAuthHolder, indicator, myForkPath, title, description, headBranch, targetBranch);
if (request == null) {
return;
}
@@ -357,14 +366,21 @@ public class GithubCreatePullRequestWorker {
@Nullable
private static GithubPullRequest createPullRequest(@NotNull Project project,
- @NotNull GithubAuthData auth,
- @NotNull GithubFullPath targetRepo,
- @NotNull String title,
- @NotNull String description,
- @NotNull String head,
- @NotNull String base) {
+ @NotNull GithubAuthDataHolder authHolder,
+ @NotNull ProgressIndicator indicator,
+ @NotNull final GithubFullPath targetRepo,
+ @NotNull final String title,
+ @NotNull final String description,
+ @NotNull final String head,
+ @NotNull final String base) {
try {
- return GithubApiUtil.createPullRequest(auth, targetRepo.getUser(), targetRepo.getRepository(), title, description, head, base);
+ return GithubUtil.runTask(project, authHolder, indicator, new ThrowableConvertor<GithubAuthData, GithubPullRequest, IOException>() {
+ @NotNull
+ @Override
+ public GithubPullRequest convert(@NotNull GithubAuthData auth) throws IOException {
+ return GithubApiUtil.createPullRequest(auth, targetRepo.getUser(), targetRepo.getRepository(), title, description, head, base);
+ }
+ });
}
catch (IOException e) {
GithubNotifications.showError(project, CANNOT_CREATE_PULL_REQUEST, e);
@@ -451,7 +467,7 @@ public class GithubCreatePullRequestWorker {
@Nullable
private static GithubInfo2 getAvailableForksInModal(@NotNull final Project project,
@NotNull final GitRepository gitRepository,
- @NotNull final GithubAuthData auth,
+ @NotNull final GithubAuthDataHolder authHolder,
@NotNull final GithubFullPath path) {
try {
return GithubUtil
@@ -462,7 +478,15 @@ public class GithubCreatePullRequestWorker {
final Set<GithubFullPath> forks = new HashSet<GithubFullPath>();
// GitHub
- GithubRepoDetailed repo = GithubApiUtil.getDetailedRepoInfo(auth, path.getUser(), path.getRepository());
+ GithubRepoDetailed repo =
+ GithubUtil.runTask(project, authHolder, indicator, new ThrowableConvertor<GithubAuthData, GithubRepoDetailed, IOException>() {
+ @NotNull
+ @Override
+ public GithubRepoDetailed convert(@NotNull GithubAuthData auth) throws IOException {
+ return GithubApiUtil.getDetailedRepoInfo(auth, path.getUser(), path.getRepository());
+ }
+ });
+
forks.add(path);
if (repo.getParent() != null) {
forks.add(repo.getParent().getFullPath());
@@ -507,10 +531,11 @@ public class GithubCreatePullRequestWorker {
@Nullable
private static GithubFullPath findRepositoryByUser(@NotNull Project project,
- @NotNull String user,
+ @NotNull GithubAuthDataHolder authHolder,
+ @NotNull ProgressIndicator indicator,
+ @NotNull final String user,
@NotNull Set<GithubFullPath> forks,
- @NotNull GithubAuthData auth,
- @NotNull GithubRepo source) {
+ @NotNull final GithubRepo source) {
for (GithubFullPath path : forks) {
if (StringUtil.equalsIgnoreCase(user, path.getUser())) {
return path;
@@ -518,20 +543,28 @@ public class GithubCreatePullRequestWorker {
}
try {
- GithubRepoDetailed target = GithubApiUtil.getDetailedRepoInfo(auth, user, source.getName());
- if (target.getSource() != null && StringUtil.equals(target.getSource().getUserName(), source.getUserName())) {
- return target.getFullPath();
- }
- }
- catch (IOException ignore) {
- // such repo may not exist
- }
+ return GithubUtil.runTask(project, authHolder, indicator, new ThrowableConvertor<GithubAuthData, GithubFullPath, IOException>() {
+ @Nullable
+ @Override
+ public GithubFullPath convert(@NotNull GithubAuthData auth) throws IOException {
+ try {
+ GithubRepoDetailed target = GithubApiUtil.getDetailedRepoInfo(auth, user, source.getName());
+ if (target.getSource() != null && StringUtil.equals(target.getSource().getUserName(), source.getUserName())) {
+ return target.getFullPath();
+ }
+ }
+ catch (IOException ignore) {
+ // such repo may not exist
+ }
- try {
- GithubRepo fork = GithubApiUtil.findForkByUser(auth, source.getUserName(), source.getName(), user);
- if (fork != null) {
- return fork.getFullPath();
- }
+ GithubRepo fork = GithubApiUtil.findForkByUser(auth, source.getUserName(), source.getName(), user);
+ if (fork != null) {
+ return fork.getFullPath();
+ }
+
+ return null;
+ }
+ });
}
catch (IOException e) {
GithubNotifications.showError(project, CANNOT_CREATE_PULL_REQUEST, e);
diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java
index d3f912545ee2..4faaf7bf568f 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java
@@ -105,7 +105,6 @@ public class GithubRebaseAction extends DumbAwareAction {
GithubNotifications.showError(project, CANNOT_PERFORM_GITHUB_REBASE, "Can't find git repository");
return;
}
-
BasicAction.saveAll();
new Task.Backgroundable(project, "Rebasing GitHub fork...") {
@@ -175,15 +174,16 @@ public class GithubRebaseAction extends DumbAwareAction {
if (GithubUtil.addGithubRemote(project, gitRepository, "upstream", parentRepoUrl)) {
return parentRepoUrl;
- } else {
+ }
+ else {
return null;
}
}
@Nullable
private static GithubRepoDetailed loadRepositoryInfo(@NotNull Project project,
- @NotNull GitRepository gitRepository,
- @NotNull ProgressIndicator indicator) {
+ @NotNull GitRepository gitRepository,
+ @NotNull ProgressIndicator indicator) {
final String remoteUrl = GithubUtil.findGithubRemoteUrl(gitRepository);
if (remoteUrl == null) {
GithubNotifications.showError(project, CANNOT_PERFORM_GITHUB_REBASE, "Can't find github remote");
@@ -196,13 +196,14 @@ public class GithubRebaseAction extends DumbAwareAction {
}
try {
- return GithubUtil.runWithValidAuth(project, indicator, new ThrowableConvertor<GithubAuthData, GithubRepoDetailed, IOException>() {
- @Override
- @NotNull
- public GithubRepoDetailed convert(GithubAuthData authData) throws IOException {
- return GithubApiUtil.getDetailedRepoInfo(authData, userAndRepo.getUser(), userAndRepo.getRepository());
- }
- });
+ return GithubUtil.runTask(project, GithubAuthDataHolder.createFromSettings(), indicator,
+ new ThrowableConvertor<GithubAuthData, GithubRepoDetailed, IOException>() {
+ @NotNull
+ @Override
+ public GithubRepoDetailed convert(@NotNull GithubAuthData auth) throws IOException {
+ return GithubApiUtil.getDetailedRepoInfo(auth, userAndRepo.getUser(), userAndRepo.getRepository());
+ }
+ });
}
catch (GithubOperationCanceledException e) {
return null;
@@ -236,7 +237,8 @@ public class GithubRebaseAction extends DumbAwareAction {
public void run() {
doRebaseCurrentBranch(project, gitRepository.getRoot(), indicator);
}
- });
+ }
+ );
process.execute();
}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java
index d3e72a278c0c..99c5ff9020c6 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java
@@ -26,13 +26,13 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vcs.VcsDataKeys;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ui.SelectFilesDialog;
import com.intellij.openapi.vcs.ui.CommitMessage;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.ThrowableConsumer;
import com.intellij.util.ThrowableConvertor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
@@ -51,18 +51,18 @@ import git4idea.util.GitUIUtil;
import icons.GithubIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.github.api.*;
+import org.jetbrains.plugins.github.api.GithubApiUtil;
+import org.jetbrains.plugins.github.api.GithubRepo;
+import org.jetbrains.plugins.github.api.GithubUserDetailed;
import org.jetbrains.plugins.github.exceptions.GithubOperationCanceledException;
import org.jetbrains.plugins.github.ui.GithubShareDialog;
-import org.jetbrains.plugins.github.util.GithubAuthData;
-import org.jetbrains.plugins.github.util.GithubNotifications;
-import org.jetbrains.plugins.github.util.GithubUrlUtil;
-import org.jetbrains.plugins.github.util.GithubUtil;
+import org.jetbrains.plugins.github.util.*;
import javax.swing.*;
import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.atomic.AtomicReference;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import static org.jetbrains.plugins.github.util.GithubUtil.setVisibleEnabled;
@@ -125,8 +125,10 @@ public class GithubShareAction extends DumbAwareAction {
externalRemoteDetected = !gitRepository.getRemotes().isEmpty();
}
+ final GithubAuthDataHolder authHolder = GithubAuthDataHolder.createFromSettings();
+
// get available GitHub repos with modal progress
- final GithubInfo githubInfo = loadGithubInfoWithModal(project);
+ final GithubInfo githubInfo = loadGithubInfoWithModal(authHolder, project);
if (githubInfo == null) {
return;
}
@@ -150,7 +152,7 @@ public class GithubShareAction extends DumbAwareAction {
// create GitHub repo (network)
LOG.info("Creating GitHub repository");
indicator.setText("Creating GitHub repository...");
- final String url = createGithubRepository(project, githubInfo.getAuthData(), name, description, isPrivate);
+ final String url = createGithubRepository(project, authHolder, indicator, name, description, isPrivate);
if (url == null) {
return;
}
@@ -202,29 +204,28 @@ public class GithubShareAction extends DumbAwareAction {
}
@Nullable
- private static GithubInfo loadGithubInfoWithModal(@NotNull final Project project) {
+ private static GithubInfo loadGithubInfoWithModal(@NotNull final GithubAuthDataHolder authHolder, @NotNull final Project project) {
try {
return GithubUtil
.computeValueInModal(project, "Access to GitHub", new ThrowableConvertor<ProgressIndicator, GithubInfo, IOException>() {
+ @NotNull
@Override
public GithubInfo convert(ProgressIndicator indicator) throws IOException {
// get existing github repos (network) and validate auth data
- final AtomicReference<List<GithubRepo>> availableReposRef = new AtomicReference<List<GithubRepo>>();
- final GithubAuthData auth =
- GithubUtil.runAndGetValidAuth(project, indicator, new ThrowableConsumer<GithubAuthData, IOException>() {
- @Override
- public void consume(GithubAuthData authData) throws IOException {
- availableReposRef.set(GithubApiUtil.getUserRepos(authData));
+ return GithubUtil.runTask(project, authHolder, indicator, new ThrowableConvertor<GithubAuthData, GithubInfo, IOException>() {
+ @NotNull
+ @Override
+ public GithubInfo convert(@NotNull GithubAuthData auth) throws IOException {
+ // check access to private repos (network)
+ GithubUserDetailed userInfo = GithubApiUtil.getCurrentUserDetailed(auth);
+
+ HashSet<String> names = new HashSet<String>();
+ for (GithubRepo info : GithubApiUtil.getUserRepos(auth)) {
+ names.add(info.getName());
}
- });
- final HashSet<String> names = new HashSet<String>();
- for (GithubRepo info : availableReposRef.get()) {
- names.add(info.getName());
- }
-
- // check access to private repos (network)
- final GithubUserDetailed userInfo = GithubApiUtil.getCurrentUserDetailed(auth);
- return new GithubInfo(auth, userInfo, names);
+ return new GithubInfo(userInfo, names);
+ }
+ });
}
});
}
@@ -239,14 +240,20 @@ public class GithubShareAction extends DumbAwareAction {
@Nullable
private static String createGithubRepository(@NotNull Project project,
- @NotNull GithubAuthData auth,
- @NotNull String name,
- @NotNull String description,
- boolean isPrivate) {
+ @NotNull GithubAuthDataHolder authHolder,
+ @NotNull ProgressIndicator indicator,
+ @NotNull final String name,
+ @NotNull final String description,
+ final boolean isPrivate) {
try {
- GithubRepo response = GithubApiUtil.createRepo(auth, name, description, isPrivate);
- return response.getHtmlUrl();
+ return GithubUtil.runTask(project, authHolder, indicator, new ThrowableConvertor<GithubAuthData, GithubRepo, IOException>() {
+ @NotNull
+ @Override
+ public GithubRepo convert(@NotNull GithubAuthData auth) throws IOException {
+ return GithubApiUtil.createRepo(auth, name, description, isPrivate);
+ }
+ }).getHtmlUrl();
}
catch (IOException e) {
GithubNotifications.showError(project, "Failed to create GitHub Repository", e);
@@ -286,15 +293,15 @@ public class GithubShareAction extends DumbAwareAction {
// ask for files to add
final List<VirtualFile> trackedFiles = ChangeListManager.getInstance(project).getAffectedFiles();
- final Collection<VirtualFile> untrackedFiles = filterOutIgnored(project,
- repository.getUntrackedFilesHolder().retrieveUntrackedFiles());
+ final Collection<VirtualFile> untrackedFiles =
+ filterOutIgnored(project, repository.getUntrackedFilesHolder().retrieveUntrackedFiles());
trackedFiles.removeAll(untrackedFiles); // fix IDEA-119855
final List<VirtualFile> allFiles = new ArrayList<VirtualFile>();
allFiles.addAll(trackedFiles);
allFiles.addAll(untrackedFiles);
- final AtomicReference<GithubUntrackedFilesDialog> dialogRef = new AtomicReference<GithubUntrackedFilesDialog>();
+ final Ref<GithubUntrackedFilesDialog> dialogRef = new Ref<GithubUntrackedFilesDialog>();
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
@@ -429,12 +436,10 @@ public class GithubShareAction extends DumbAwareAction {
private static class GithubInfo {
@NotNull private final GithubUserDetailed myUser;
- @NotNull private final GithubAuthData myAuthData;
@NotNull private final HashSet<String> myRepositoryNames;
- GithubInfo(@NotNull GithubAuthData auth, @NotNull GithubUserDetailed user, @NotNull HashSet<String> repositoryNames) {
+ GithubInfo(@NotNull GithubUserDetailed user, @NotNull HashSet<String> repositoryNames) {
myUser = user;
- myAuthData = auth;
myRepositoryNames = repositoryNames;
}
@@ -444,11 +449,6 @@ public class GithubShareAction extends DumbAwareAction {
}
@NotNull
- public GithubAuthData getAuthData() {
- return myAuthData;
- }
-
- @NotNull
public HashSet<String> getRepositoryNames() {
return myRepositoryNames;
}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
index ec7d3ae2b51d..581dc16bf25b 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
@@ -169,6 +169,10 @@ public class GithubApiUtil {
if (tokenAuth != null) {
method.addRequestHeader("Authorization", "token " + tokenAuth.getToken());
}
+ GithubAuthData.BasicAuth basicAuth = auth.getBasicAuth();
+ if (basicAuth != null && basicAuth.getCode() != null) {
+ method.addRequestHeader("X-GitHub-OTP", basicAuth.getCode());
+ }
for (Header header : headers) {
method.addRequestHeader(header);
}
@@ -401,6 +405,14 @@ public class GithubApiUtil {
* Github API
*/
+ public static void askForTwoFactorCodeSMS(@NotNull GithubAuthData auth) {
+ try {
+ postRequest(auth, "/authorizations", null, ACCEPT_V3_JSON);
+ } catch (IOException e) {
+ LOG.info(e);
+ }
+ }
+
@NotNull
public static Collection<String> getTokenScopes(@NotNull GithubAuthData auth) throws IOException {
HttpMethod method = null;
@@ -448,10 +460,9 @@ public class GithubApiUtil {
@NotNull
public static String getMasterToken(@NotNull GithubAuthData auth, @Nullable String note) throws IOException {
- List<String> scopes = new ArrayList<String>();
-
- scopes.add("repo"); // read/write access to public/private repositories
- scopes.add("gist"); // create/delete gists
+ // "repo" - read/write access to public/private repositories
+ // "gist" - create/delete gists
+ List<String> scopes = Arrays.asList("repo", "gist");
return getScopedToken(auth, scopes, note);
}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubCheckoutProvider.java b/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubCheckoutProvider.java
index 668913836dbd..ee117b0bdef9 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubCheckoutProvider.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubCheckoutProvider.java
@@ -32,6 +32,7 @@ import org.jetbrains.plugins.github.api.GithubApiUtil;
import org.jetbrains.plugins.github.api.GithubRepo;
import org.jetbrains.plugins.github.exceptions.GithubOperationCanceledException;
import org.jetbrains.plugins.github.util.GithubAuthData;
+import org.jetbrains.plugins.github.util.GithubAuthDataHolder;
import org.jetbrains.plugins.github.util.GithubNotifications;
import org.jetbrains.plugins.github.util.GithubUtil;
@@ -60,12 +61,15 @@ public class GithubCheckoutProvider implements CheckoutProvider {
@NotNull
@Override
public List<GithubRepo> convert(ProgressIndicator indicator) throws IOException {
- return GithubUtil.runWithValidAuth(project, indicator, new ThrowableConvertor<GithubAuthData, List<GithubRepo>, IOException>() {
- @Override
- public List<GithubRepo> convert(GithubAuthData authData) throws IOException {
- return GithubApiUtil.getAvailableRepos(authData);
- }
- });
+ return GithubUtil.runTask(project, GithubAuthDataHolder.createFromSettings(), indicator,
+ new ThrowableConvertor<GithubAuthData, List<GithubRepo>, IOException>() {
+ @NotNull
+ @Override
+ public List<GithubRepo> convert(@NotNull GithubAuthData auth) throws IOException {
+ return GithubApiUtil.getAvailableRepos(auth);
+ }
+ }
+ );
}
});
}
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 568a010eaeb6..a340de0f62f1 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubHttpAuthDataProvider.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubHttpAuthDataProvider.java
@@ -37,6 +37,9 @@ public class GithubHttpAuthDataProvider implements GitHttpAuthDataProvider {
}
GithubSettings settings = GithubSettings.getInstance();
+ if (!settings.isValidGitAuth()) {
+ return null;
+ }
String host1 = GithubUrlUtil.getHostFromUrl(settings.getHost());
String host2 = GithubUrlUtil.getHostFromUrl(url);
diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java
index 8af4136507f5..059be25cb7e3 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java
@@ -13,11 +13,12 @@ import com.intellij.util.ui.FormBuilder;
import com.intellij.util.ui.GridBag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.github.api.GithubApiUtil;
import org.jetbrains.plugins.github.exceptions.GithubOperationCanceledException;
import org.jetbrains.plugins.github.util.GithubAuthData;
+import org.jetbrains.plugins.github.util.GithubAuthDataHolder;
import org.jetbrains.plugins.github.util.GithubNotifications;
import org.jetbrains.plugins.github.util.GithubUtil;
-import org.jetbrains.plugins.github.api.GithubApiUtil;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
@@ -124,15 +125,19 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor
@Override
public String convert(ProgressIndicator indicator) throws IOException {
return GithubUtil
- .runWithValidBasicAuthForHost(myProject, indicator, getHost(), new ThrowableConvertor<GithubAuthData, String, IOException>() {
- @NotNull
- @Override
- public String convert(GithubAuthData auth) throws IOException {
- return GithubApiUtil.getReadOnlyToken(auth, getRepoAuthor(), getRepoName(), "Intellij tasks plugin");
- }
- });
+ .runTaskWithBasicAuthForHost(myProject, GithubAuthDataHolder.createFromSettings(), indicator, getHost(),
+ new ThrowableConvertor<GithubAuthData, String, IOException>() {
+ @NotNull
+ @Override
+ public String convert(@NotNull GithubAuthData auth) throws IOException {
+ return GithubApiUtil
+ .getReadOnlyToken(auth, getRepoAuthor(), getRepoName(), "Intellij tasks plugin");
+ }
+ }
+ );
}
- }));
+ })
+ );
}
catch (GithubOperationCanceledException ignore) {
}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubBasicLoginDialog.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubBasicLoginDialog.java
index fac45c597980..80acc787d6c6 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubBasicLoginDialog.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubBasicLoginDialog.java
@@ -16,25 +16,17 @@
package org.jetbrains.plugins.github.ui;
import com.intellij.openapi.project.Project;
-import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.github.util.GithubAuthData;
-import org.jetbrains.plugins.github.util.GithubSettings;
/**
* @author Aleksey Pivovarov
*/
public class GithubBasicLoginDialog extends GithubLoginDialog {
- public GithubBasicLoginDialog(@Nullable Project project) {
- super(project);
+ public GithubBasicLoginDialog(@NotNull Project project, @NotNull GithubAuthData oldAuthData, @NotNull String host) {
+ super(project, oldAuthData);
myGithubLoginPanel.lockAuthType(GithubAuthData.AuthType.BASIC);
- }
-
- @Override
- protected void saveCredentials(GithubAuthData auth) {
- final GithubSettings settings = GithubSettings.getInstance();
- if (settings.getAuthType() != GithubAuthData.AuthType.TOKEN) {
- settings.setCredentials(myGithubLoginPanel.getHost(), auth, myGithubLoginPanel.isSavePasswordSelected());
- }
+ myGithubLoginPanel.lockHost(host);
}
}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java
index 7660fb569b7f..c4e33f6e136c 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java
@@ -6,9 +6,9 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.util.ThrowableConvertor;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.api.GithubUser;
import org.jetbrains.plugins.github.util.GithubAuthData;
+import org.jetbrains.plugins.github.util.GithubAuthDataHolder;
import org.jetbrains.plugins.github.util.GithubSettings;
import org.jetbrains.plugins.github.util.GithubUtil;
@@ -25,18 +25,25 @@ public class GithubLoginDialog extends DialogWrapper {
protected final GithubLoginPanel myGithubLoginPanel;
protected final GithubSettings mySettings;
+
protected final Project myProject;
- public GithubLoginDialog(@Nullable final Project project) {
+ protected GithubAuthData myAuthData;
+
+ public GithubLoginDialog(@NotNull final Project project, @NotNull GithubAuthData oldAuthData) {
super(project, true);
myProject = project;
+
myGithubLoginPanel = new GithubLoginPanel(this);
- mySettings = GithubSettings.getInstance();
- myGithubLoginPanel.setHost(mySettings.getHost());
- myGithubLoginPanel.setLogin(mySettings.getLogin());
- myGithubLoginPanel.setAuthType(mySettings.getAuthType());
+ myGithubLoginPanel.setHost(oldAuthData.getHost());
+ myGithubLoginPanel.setAuthType(oldAuthData.getAuthType());
+ GithubAuthData.BasicAuth basicAuth = oldAuthData.getBasicAuth();
+ if (basicAuth != null) {
+ myGithubLoginPanel.setLogin(basicAuth.getLogin());
+ }
+ mySettings = GithubSettings.getInstance();
if (mySettings.isSavePasswordMakesSense()) {
myGithubLoginPanel.setSavePasswordSelected(mySettings.isSavePassword());
}
@@ -71,17 +78,18 @@ public class GithubLoginDialog extends DialogWrapper {
@Override
protected void doOKAction() {
- final GithubAuthData auth = myGithubLoginPanel.getAuthData();
+ final GithubAuthDataHolder authHolder = new GithubAuthDataHolder(myGithubLoginPanel.getAuthData());
try {
GithubUtil.computeValueInModal(myProject, "Access to GitHub", new ThrowableConvertor<ProgressIndicator, GithubUser, IOException>() {
@NotNull
@Override
public GithubUser convert(ProgressIndicator indicator) throws IOException {
- return GithubUtil.checkAuthData(auth);
+ return GithubUtil.checkAuthData(myProject, authHolder, indicator);
}
});
- saveCredentials(auth);
+ myAuthData = authHolder.getAuthData();
+
if (mySettings.isSavePasswordMakesSense()) {
mySettings.setSavePassword(myGithubLoginPanel.isSavePasswordSelected());
}
@@ -93,21 +101,19 @@ public class GithubLoginDialog extends DialogWrapper {
}
}
- protected void saveCredentials(GithubAuthData auth) {
- final GithubSettings settings = GithubSettings.getInstance();
- settings.setCredentials(myGithubLoginPanel.getHost(), auth, myGithubLoginPanel.isSavePasswordSelected());
- }
-
- public void clearErrors() {
- setErrorText(null);
+ public boolean isSavePasswordSelected() {
+ return myGithubLoginPanel.isSavePasswordSelected();
}
@NotNull
public GithubAuthData getAuthData() {
- return myGithubLoginPanel.getAuthData();
+ if (myAuthData == null) {
+ throw new IllegalStateException("AuthData is not set");
+ }
+ return myAuthData;
}
- public void lockHost(String host) {
- myGithubLoginPanel.lockHost(host);
+ public void clearErrors() {
+ setErrorText(null);
}
} \ No newline at end of file
diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java
index 9e8f9ab300ae..80e5a6fb8d8e 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java
@@ -100,7 +100,7 @@ public class GithubSettingsPanel {
@NotNull
@Override
public GithubUser convert(ProgressIndicator indicator) throws IOException {
- return GithubUtil.checkAuthData(auth);
+ return GithubUtil.checkAuthData(project, new GithubAuthDataHolder(auth), indicator);
}
});
@@ -132,13 +132,14 @@ public class GithubSettingsPanel {
@NotNull
@Override
public String convert(ProgressIndicator indicator) throws IOException {
- return GithubUtil.runWithValidBasicAuthForHost(project, indicator, getHost(),
- new ThrowableConvertor<GithubAuthData, String, IOException>() {
- @Override
- public String convert(GithubAuthData auth) throws IOException {
- return GithubApiUtil.getMasterToken(auth, "IntelliJ plugin");
- }
- }
+ return GithubUtil.runTaskWithBasicAuthForHost(project, GithubAuthDataHolder.createFromSettings(), indicator, getHost(),
+ new ThrowableConvertor<GithubAuthData, String, IOException>() {
+ @NotNull
+ @Override
+ public String convert(@NotNull GithubAuthData auth) throws IOException {
+ return GithubApiUtil.getMasterToken(auth, "IntelliJ plugin");
+ }
+ }
);
}
})
@@ -294,7 +295,7 @@ public class GithubSettingsPanel {
public void apply() {
if (myCredentialsModified) {
- mySettings.setCredentials(getHost(), getAuthData(), true);
+ mySettings.setAuthData(getAuthData(), true);
}
mySettings.setConnectionTimeout(getConnectionTimeout());
resetCredentialsModification();
diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.java
index 63e93a6e230e..f11044422154 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.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,10 +21,12 @@ import org.jetbrains.plugins.github.api.GithubApiUtil;
/**
* Container for authentication data:
- * - host
- * - login
+ * * host
+ * * credentials
* - login/password pair
- * or
+ * or
+ * - login/password pair/2 factor code
+ * or
* - OAuth2 access token
*
* @author Aleksey Pivovarov
@@ -38,7 +40,6 @@ public class GithubAuthData {
@Nullable private final TokenAuth myTokenAuth;
private final boolean myUseProxy;
-
private GithubAuthData(@NotNull AuthType authType,
@NotNull String host,
@Nullable BasicAuth basicAuth,
@@ -51,6 +52,10 @@ public class GithubAuthData {
myUseProxy = useProxy;
}
+ public static GithubAuthData createFromSettings() {
+ return GithubSettings.getInstance().getAuthData();
+ }
+
public static GithubAuthData createAnonymous() {
return createAnonymous(GithubApiUtil.DEFAULT_GITHUB_HOST);
}
@@ -63,6 +68,13 @@ public class GithubAuthData {
return new GithubAuthData(AuthType.BASIC, host, new BasicAuth(login, password), null, true);
}
+ public static GithubAuthData createBasicAuthTF(@NotNull String host,
+ @NotNull String login,
+ @NotNull String password,
+ @NotNull String code) {
+ return new GithubAuthData(AuthType.BASIC, host, new BasicAuth(login, password, code), null, true);
+ }
+
public static GithubAuthData createTokenAuth(@NotNull String host, @NotNull String token) {
return new GithubAuthData(AuthType.TOKEN, host, null, new TokenAuth(token), true);
}
@@ -95,13 +107,28 @@ public class GithubAuthData {
return myUseProxy;
}
+ @NotNull
+ public GithubAuthData copyWithTwoFactorCode(@NotNull String code) {
+ if (myBasicAuth == null) {
+ throw new IllegalStateException("Two factor authentication can be used only with Login/Password");
+ }
+
+ return createBasicAuthTF(getHost(), myBasicAuth.getLogin(), myBasicAuth.getPassword(), code);
+ }
+
public static class BasicAuth {
@NotNull private final String myLogin;
@NotNull private final String myPassword;
+ @Nullable private final String myCode;
private BasicAuth(@NotNull String login, @NotNull String password) {
+ this(login, password, null);
+ }
+
+ private BasicAuth(@NotNull String login, @NotNull String password, @Nullable String code) {
myLogin = login;
myPassword = password;
+ myCode = code;
}
@NotNull
@@ -113,6 +140,11 @@ public class GithubAuthData {
public String getPassword() {
return myPassword;
}
+
+ @Nullable
+ public String getCode() {
+ return myCode;
+ }
}
public static class TokenAuth {
diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthDataHolder.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthDataHolder.java
new file mode 100644
index 000000000000..695dfe734c34
--- /dev/null
+++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthDataHolder.java
@@ -0,0 +1,46 @@
+/*
+ * 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 org.jetbrains.plugins.github.util;
+
+import com.intellij.openapi.util.ThrowableComputable;
+import org.jetbrains.annotations.NotNull;
+
+
+public class GithubAuthDataHolder {
+ @NotNull private GithubAuthData myAuthData;
+
+ public GithubAuthDataHolder(@NotNull GithubAuthData auth) {
+ myAuthData = auth;
+ }
+
+ @NotNull
+ public synchronized GithubAuthData getAuthData() {
+ return myAuthData;
+ }
+
+ public synchronized <T extends Throwable> void runTransaction(@NotNull GithubAuthData expected,
+ @NotNull ThrowableComputable<GithubAuthData, T> task) throws T {
+ if (expected != myAuthData) {
+ return;
+ }
+
+ myAuthData = task.compute();
+ }
+
+ public static GithubAuthDataHolder createFromSettings() {
+ return new GithubAuthDataHolder(GithubSettings.getInstance().getAuthData());
+ }
+}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java
index 49199c0d156b..3523e412a95e 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java
@@ -59,6 +59,7 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S
public boolean PRIVATE_GIST = true;
public boolean SAVE_PASSWORD = true;
public int CONNECTION_TIMEOUT = 5000;
+ public boolean VALID_GIT_AUTH = true;
}
public static GithubSettings getInstance() {
@@ -120,6 +121,10 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S
return myState.SAVE_PASSWORD;
}
+ public boolean isValidGitAuth() {
+ return myState.VALID_GIT_AUTH;
+ }
+
public boolean isSavePasswordMakesSense() {
final PasswordSafeImpl passwordSafe = (PasswordSafeImpl)PasswordSafe.getInstance();
return passwordSafe.getSettings().getProviderType() == PasswordSafeSettings.ProviderType.MASTER_PASSWORD;
@@ -137,6 +142,10 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S
myState.SAVE_PASSWORD = savePassword;
}
+ public void setValidGitAuth(final boolean validGitAuth) {
+ myState.VALID_GIT_AUTH = validGitAuth;
+ }
+
public void setOpenInBrowserGist(final boolean openInBrowserGist) {
myState.OPEN_IN_BROWSER_GIST = openInBrowserGist;
}
@@ -172,10 +181,25 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S
}
}
+ private static boolean isValidGitAuth(@NotNull GithubAuthData auth) {
+ switch (auth.getAuthType()) {
+ case BASIC:
+ assert auth.getBasicAuth() != null;
+ return auth.getBasicAuth().getCode() == null;
+ case TOKEN:
+ return true;
+ case ANONYMOUS:
+ return false;
+ default:
+ throw new IllegalStateException("GithubSettings: setAuthData - wrong AuthType: " + auth.getAuthType());
+ }
+ }
+
@NotNull
public GithubAuthData getAuthData() {
switch (getAuthType()) {
case BASIC:
+ //noinspection ConstantConditions
return GithubAuthData.createBasicAuth(getHost(), getLogin(), getPassword());
case TOKEN:
return GithubAuthData.createTokenAuth(getHost(), getPassword());
@@ -186,8 +210,11 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S
}
}
- private void setAuthData(@NotNull GithubAuthData auth, boolean rememberPassword) {
+ public void setAuthData(@NotNull GithubAuthData auth, boolean rememberPassword) {
+ setValidGitAuth(isValidGitAuth(auth));
+
setAuthType(auth.getAuthType());
+ setHost(auth.getHost());
switch (auth.getAuthType()) {
case BASIC:
@@ -205,12 +232,7 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S
setPassword("", rememberPassword);
break;
default:
- throw new IllegalStateException("GithubSettings: setAuthData - wrong AuthType: " + getAuthType());
+ throw new IllegalStateException("GithubSettings: setAuthData - wrong AuthType: " + auth.getAuthType());
}
}
-
- public void setCredentials(@NotNull String host, @NotNull GithubAuthData auth, boolean rememberPassword) {
- setHost(host);
- setAuthData(auth, rememberPassword);
- }
} \ No newline at end of file
diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubUrlUtil.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubUrlUtil.java
index a79a2f4147e1..d65b5d7315fc 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubUrlUtil.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubUrlUtil.java
@@ -126,6 +126,7 @@ public class GithubUrlUtil {
}
public static boolean isGithubUrl(@NotNull String url, @NotNull String host) {
+ host = getHostFromUrl(host);
url = removeProtocolPrefix(url);
if (StringUtil.startsWithIgnoreCase(url, host)) {
if (url.length() > host.length() && ":/".indexOf(url.charAt(host.length())) == -1) {
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 a3eb6c4ca1d7..db137884f764 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubUtil.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubUtil.java
@@ -22,7 +22,10 @@ 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.ui.Messages;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
@@ -46,13 +49,13 @@ import org.jetbrains.plugins.github.api.GithubFullPath;
import org.jetbrains.plugins.github.api.GithubUserDetailed;
import org.jetbrains.plugins.github.exceptions.GithubAuthenticationException;
import org.jetbrains.plugins.github.exceptions.GithubOperationCanceledException;
+import org.jetbrains.plugins.github.exceptions.GithubTwoFactorAuthenticationException;
import org.jetbrains.plugins.github.ui.GithubBasicLoginDialog;
import org.jetbrains.plugins.github.ui.GithubLoginDialog;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
/**
* Various utility methods for the GutHub plugin.
@@ -65,119 +68,194 @@ public class GithubUtil {
public static final Logger LOG = Logger.getInstance("github");
- // TODO: these functions ugly inside and out
+ // TODO: Consider sharing of GithubAuthData between actions (as member of GithubSettings)
@NotNull
- public static GithubAuthData runAndGetValidAuth(@Nullable Project project,
- @NotNull ProgressIndicator indicator,
- @NotNull ThrowableConsumer<GithubAuthData, IOException> task) throws IOException {
- GithubAuthData auth = GithubSettings.getInstance().getAuthData();
+ public static <T> T runTask(@NotNull Project project,
+ @NotNull GithubAuthDataHolder authHolder,
+ @NotNull ProgressIndicator indicator,
+ @NotNull ThrowableConvertor<GithubAuthData, T, IOException> task) throws IOException {
+ GithubAuthData auth = authHolder.getAuthData();
try {
- if (auth.getAuthType() == GithubAuthData.AuthType.ANONYMOUS) {
- throw new GithubAuthenticationException("Bad authentication type");
- }
- task.consume(auth);
- return auth;
+ return task.convert(auth);
+ }
+ catch (GithubTwoFactorAuthenticationException e) {
+ getTwoFactorAuthData(project, authHolder, indicator, auth);
+ return runTask(project, authHolder, indicator, task);
}
catch (GithubAuthenticationException e) {
- auth = getValidAuthData(project, indicator);
- task.consume(auth);
- return auth;
+ getValidAuthData(project, authHolder, indicator, auth);
+ return runTask(project, authHolder, indicator, task);
}
}
- @NotNull
- public static <T> T runWithValidAuth(@Nullable Project project,
- @NotNull ProgressIndicator indicator,
- @NotNull ThrowableConvertor<GithubAuthData, T, IOException> task) throws IOException {
- GithubAuthData auth = GithubSettings.getInstance().getAuthData();
+ public static void runTask(@NotNull Project project,
+ @NotNull GithubAuthDataHolder authHolder,
+ @NotNull ProgressIndicator indicator,
+ @NotNull ThrowableConsumer<GithubAuthData, IOException> task) throws IOException {
+ GithubAuthData auth = authHolder.getAuthData();
try {
- if (auth.getAuthType() == GithubAuthData.AuthType.ANONYMOUS) {
- throw new GithubAuthenticationException("Bad authentication type");
- }
- return task.convert(auth);
+ task.consume(auth);
+ }
+ catch (GithubTwoFactorAuthenticationException e) {
+ getTwoFactorAuthData(project, authHolder, indicator, auth);
+ runTask(project, authHolder, indicator, task);
}
catch (GithubAuthenticationException e) {
- auth = getValidAuthData(project, indicator);
- return task.convert(auth);
+ getValidAuthData(project, authHolder, indicator, auth);
+ runTask(project, authHolder, indicator, task);
}
}
@NotNull
- public static <T> T runWithValidBasicAuthForHost(@Nullable Project project,
- @NotNull ProgressIndicator indicator,
- @NotNull String host,
- @NotNull ThrowableConvertor<GithubAuthData, T, IOException> task) throws IOException {
- GithubSettings settings = GithubSettings.getInstance();
- GithubAuthData auth = null;
+ public static <T> T runTaskWithBasicAuthForHost(@NotNull Project project,
+ @NotNull GithubAuthDataHolder authHolder,
+ @NotNull ProgressIndicator indicator,
+ @NotNull String host,
+ @NotNull ThrowableConvertor<GithubAuthData, T, IOException> task) throws IOException {
+ GithubAuthData auth = authHolder.getAuthData();
try {
- if (settings.getAuthType() != GithubAuthData.AuthType.BASIC ||
- !StringUtil.equalsIgnoreCase(GithubUrlUtil.getApiUrl(host), GithubUrlUtil.getApiUrl(settings.getHost()))) {
- throw new GithubAuthenticationException("Bad authentication type");
+ if (auth.getAuthType() != GithubAuthData.AuthType.BASIC) {
+ throw new GithubAuthenticationException("Expected basic authentication");
}
- auth = settings.getAuthData();
return task.convert(auth);
}
+ catch (GithubTwoFactorAuthenticationException e) {
+ getTwoFactorAuthData(project, authHolder, indicator, auth);
+ return runTaskWithBasicAuthForHost(project, authHolder, indicator, host, task);
+ }
catch (GithubAuthenticationException e) {
- auth = getValidBasicAuthDataForHost(project, indicator, host);
- return task.convert(auth);
+ getValidBasicAuthDataForHost(project, authHolder, indicator, auth, host);
+ return runTaskWithBasicAuthForHost(project, authHolder, indicator, host, task);
}
}
- /**
- * @return null if user canceled login dialog. Valid GithubAuthData otherwise.
- */
@NotNull
- public static GithubAuthData getValidAuthData(@Nullable Project project, @NotNull ProgressIndicator indicator)
- throws GithubOperationCanceledException {
- final GithubLoginDialog dialog = new GithubLoginDialog(project);
- ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+ private static GithubUserDetailed testConnection(@NotNull Project project,
+ @NotNull GithubAuthDataHolder authHolder,
+ @NotNull ProgressIndicator indicator) throws IOException {
+ GithubAuthData auth = authHolder.getAuthData();
+ try {
+ return GithubApiUtil.getCurrentUserDetailed(auth);
+ }
+ catch (GithubTwoFactorAuthenticationException e) {
+ getTwoFactorAuthData(project, authHolder, indicator, auth);
+ return testConnection(project, authHolder, indicator);
+ }
+ }
+
+ public static void getValidAuthData(@NotNull final Project project,
+ @NotNull final GithubAuthDataHolder authHolder,
+ @NotNull final ProgressIndicator indicator,
+ @NotNull final GithubAuthData oldAuth) throws GithubOperationCanceledException {
+ authHolder.runTransaction(oldAuth, new ThrowableComputable<GithubAuthData, GithubOperationCanceledException>() {
@Override
- public void run() {
- DialogManager.show(dialog);
+ @NotNull
+ public GithubAuthData compute() throws GithubOperationCanceledException {
+ final GithubLoginDialog dialog = new GithubLoginDialog(project, oldAuth);
+ ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ DialogManager.show(dialog);
+ }
+ }, indicator.getModalityState());
+ if (!dialog.isOK()) {
+ throw new GithubOperationCanceledException("Can't get valid credentials");
+ }
+ GithubAuthData authData = dialog.getAuthData();
+
+ GithubSettings.getInstance().setAuthData(authData, dialog.isSavePasswordSelected());
+ return authData;
}
- }, indicator.getModalityState());
- if (!dialog.isOK()) {
- throw new GithubOperationCanceledException("Can't get valid credentials");
- }
- return dialog.getAuthData();
+ });
}
- /**
- * @return null if user canceled login dialog. Valid GithubAuthData otherwise.
- */
- @NotNull
- public static GithubAuthData getValidBasicAuthDataForHost(@Nullable Project project,
- @NotNull ProgressIndicator indicator,
- @NotNull String host) throws GithubOperationCanceledException {
- final GithubLoginDialog dialog = new GithubBasicLoginDialog(project);
- dialog.lockHost(host);
- ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+ public static void getValidBasicAuthDataForHost(@NotNull final Project project,
+ @NotNull final GithubAuthDataHolder authHolder,
+ @NotNull final ProgressIndicator indicator,
+ @NotNull final GithubAuthData oldAuth,
+ @NotNull final String host) throws GithubOperationCanceledException {
+ authHolder.runTransaction(oldAuth, new ThrowableComputable<GithubAuthData, GithubOperationCanceledException>() {
@Override
- public void run() {
- DialogManager.show(dialog);
+ @NotNull
+ public GithubAuthData compute() throws GithubOperationCanceledException {
+ final GithubLoginDialog dialog = new GithubBasicLoginDialog(project, oldAuth, host);
+ ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ DialogManager.show(dialog);
+ }
+ }, indicator.getModalityState());
+ if (!dialog.isOK()) {
+ 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;
}
- }, indicator.getModalityState());
- if (!dialog.isOK()) {
- throw new GithubOperationCanceledException("Can't get valid credentials");
- }
- return dialog.getAuthData();
+ });
+ }
+
+ private static void getTwoFactorAuthData(@NotNull final Project project,
+ @NotNull final GithubAuthDataHolder authHolder,
+ @NotNull final ProgressIndicator indicator,
+ @NotNull final GithubAuthData oldAuth) throws GithubOperationCanceledException {
+ authHolder.runTransaction(oldAuth, new ThrowableComputable<GithubAuthData, GithubOperationCanceledException>() {
+ @Override
+ @NotNull
+ public GithubAuthData compute() throws GithubOperationCanceledException {
+ if (authHolder.getAuthData().getAuthType() != GithubAuthData.AuthType.BASIC) {
+ throw new GithubOperationCanceledException("Two factor authentication can be used only with Login/Password");
+ }
+
+ GithubApiUtil.askForTwoFactorCodeSMS(oldAuth);
+
+ final Ref<String> codeRef = new Ref<String>();
+ ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ codeRef.set(Messages.showInputDialog(project, "Authentication Code", "Github Two-Factor Authentication", null));
+ }
+ }, indicator.getModalityState());
+ if (codeRef.isNull()) {
+ throw new GithubOperationCanceledException("Can't get two factor authentication code");
+ }
+
+ GithubSettings settings = GithubSettings.getInstance();
+ if (settings.getAuthType() == GithubAuthData.AuthType.BASIC &&
+ StringUtil.equalsIgnoreCase(settings.getLogin(), oldAuth.getBasicAuth().getLogin())) {
+ settings.setValidGitAuth(false);
+ }
+
+ return oldAuth.copyWithTwoFactorCode(codeRef.get());
+ }
+ });
}
@NotNull
- public static GithubAuthData getValidAuthDataFromConfig(@Nullable Project project, @NotNull ProgressIndicator indicator)
+ public static GithubAuthDataHolder getValidAuthDataHolderFromConfig(@NotNull Project project, @NotNull ProgressIndicator indicator)
throws IOException {
- GithubAuthData auth = GithubSettings.getInstance().getAuthData();
+ GithubAuthData auth = GithubAuthData.createFromSettings();
+ GithubAuthDataHolder authHolder = new GithubAuthDataHolder(auth);
try {
- checkAuthData(auth);
- return auth;
+ checkAuthData(project, authHolder, indicator);
+ return authHolder;
}
catch (GithubAuthenticationException e) {
- return getValidAuthData(project, indicator);
+ getValidAuthData(project, authHolder, indicator, auth);
+ return authHolder;
}
}
@NotNull
- public static GithubUserDetailed checkAuthData(@NotNull GithubAuthData auth) throws IOException {
+ public static GithubUserDetailed checkAuthData(@NotNull Project project,
+ @NotNull GithubAuthDataHolder authHolder,
+ @NotNull ProgressIndicator indicator) throws IOException {
+ GithubAuthData auth = authHolder.getAuthData();
+
if (StringUtil.isEmptyOrSpaces(auth.getHost())) {
throw new GithubAuthenticationException("Target host not defined");
}
@@ -201,37 +279,31 @@ public class GithubUtil {
throw new GithubAuthenticationException("Anonymous connection not allowed");
}
- return testConnection(auth);
+ return testConnection(project, authHolder, indicator);
}
- @NotNull
- private static GithubUserDetailed testConnection(@NotNull GithubAuthData auth) throws IOException {
- return GithubApiUtil.getCurrentUserDetailed(auth);
- }
-
- public static <T, E extends Throwable> T computeValueInModal(@NotNull Project project,
- @NotNull String caption,
- @NotNull final ThrowableConvertor<ProgressIndicator, T, E> task) throws E {
- final AtomicReference<T> dataRef = new AtomicReference<T>();
- final AtomicReference<E> exceptionRef = new AtomicReference<E>();
+ public static <T> T computeValueInModal(@NotNull Project project,
+ @NotNull String caption,
+ @NotNull final ThrowableConvertor<ProgressIndicator, T, IOException> task) throws IOException {
+ final Ref<T> dataRef = new Ref<T>();
+ final Ref<IOException> exceptionRef = new Ref<IOException>();
ProgressManager.getInstance().run(new Task.Modal(project, caption, true) {
public void run(@NotNull ProgressIndicator indicator) {
try {
dataRef.set(task.convert(indicator));
}
+ catch (IOException e) {
+ exceptionRef.set(e);
+ }
catch (Error e) {
- throw e;
+ exceptionRef.set(new GithubOperationCanceledException(e));
}
catch (RuntimeException e) {
- throw e;
- }
- catch (Throwable e) {
- //noinspection unchecked
- exceptionRef.set((E)e);
+ exceptionRef.set(new GithubOperationCanceledException(e));
}
}
});
- if (exceptionRef.get() != null) {
+ if (!exceptionRef.isNull()) {
throw exceptionRef.get();
}
return dataRef.get();
@@ -240,7 +312,7 @@ public class GithubUtil {
public static <T> T computeValueInModal(@NotNull Project project,
@NotNull String caption,
@NotNull final Convertor<ProgressIndicator, T> task) {
- final AtomicReference<T> dataRef = new AtomicReference<T>();
+ final Ref<T> dataRef = new Ref<T>();
ProgressManager.getInstance().run(new Task.Modal(project, caption, true) {
public void run(@NotNull ProgressIndicator indicator) {
dataRef.set(task.convert(indicator));
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTest.java b/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTest.java
index 0d394d58f09d..f7ae343204f2 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTest.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTest.java
@@ -15,8 +15,11 @@
*/
package org.jetbrains.plugins.github;
+import com.intellij.mock.MockProgressIndicator;
import com.intellij.notification.NotificationType;
+import com.intellij.openapi.progress.ProgressIndicator;
import org.jetbrains.plugins.github.util.GithubAuthData;
+import org.jetbrains.plugins.github.util.GithubAuthDataHolder;
import java.util.Collections;
import java.util.List;
@@ -27,10 +30,12 @@ import static org.jetbrains.plugins.github.api.GithubGist.FileContent;
* @author Aleksey Pivovarov
*/
public class GithubCreateGistTest extends GithubCreateGistTestBase {
+ private final ProgressIndicator myIndicator = new MockProgressIndicator();
+
public void testSimple() throws Throwable {
List<FileContent> expected = createContent();
- String url = GithubCreateGistAction.createGist(myProject, myGitHubSettings.getAuthData(), expected, true, GIST_DESCRIPTION, null);
+ String url = GithubCreateGistAction.createGist(myProject, getAuthDataHolder(), myIndicator, expected, true, GIST_DESCRIPTION, null);
assertNotNull(url);
GIST_ID = url.substring(url.lastIndexOf('/') + 1);
@@ -44,7 +49,9 @@ public class GithubCreateGistTest extends GithubCreateGistTestBase {
public void testAnonymous() throws Throwable {
List<FileContent> expected = createContent();
- String url = GithubCreateGistAction.createGist(myProject, GithubAuthData.createAnonymous(myHost), expected, true, GIST_DESCRIPTION, null);
+ String url = GithubCreateGistAction
+ .createGist(myProject, new GithubAuthDataHolder(GithubAuthData.createAnonymous(myHost)), myIndicator, expected, true,
+ GIST_DESCRIPTION, null);
assertNotNull(url);
GIST_ID = url.substring(url.lastIndexOf('/') + 1);
@@ -62,7 +69,8 @@ public class GithubCreateGistTest extends GithubCreateGistTestBase {
public void testUnusedFilenameField() throws Throwable {
List<FileContent> expected = createContent();
- String url = GithubCreateGistAction.createGist(myProject, myGitHubSettings.getAuthData(), expected, true, GIST_DESCRIPTION, "filename");
+ String url =
+ GithubCreateGistAction.createGist(myProject, getAuthDataHolder(), myIndicator, expected, true, GIST_DESCRIPTION, "filename");
assertNotNull(url);
GIST_ID = url.substring(url.lastIndexOf('/') + 1);
@@ -77,7 +85,8 @@ public class GithubCreateGistTest extends GithubCreateGistTestBase {
List<FileContent> content = Collections.singletonList(new FileContent("file.txt", "file.txt content"));
List<FileContent> expected = Collections.singletonList(new FileContent("filename", "file.txt content"));
- String url = GithubCreateGistAction.createGist(myProject, myGitHubSettings.getAuthData(), content, true, GIST_DESCRIPTION, "filename");
+ String url =
+ GithubCreateGistAction.createGist(myProject, getAuthDataHolder(), myIndicator, content, true, GIST_DESCRIPTION, "filename");
assertNotNull(url);
GIST_ID = url.substring(url.lastIndexOf('/') + 1);
@@ -91,7 +100,7 @@ public class GithubCreateGistTest extends GithubCreateGistTestBase {
public void testPublic() throws Throwable {
List<FileContent> expected = createContent();
- String url = GithubCreateGistAction.createGist(myProject, myGitHubSettings.getAuthData(), expected, false, GIST_DESCRIPTION, null);
+ String url = GithubCreateGistAction.createGist(myProject, getAuthDataHolder(), myIndicator, expected, false, GIST_DESCRIPTION, null);
assertNotNull(url);
GIST_ID = url.substring(url.lastIndexOf('/') + 1);
@@ -105,33 +114,35 @@ public class GithubCreateGistTest extends GithubCreateGistTestBase {
public void testEmpty() throws Throwable {
List<FileContent> expected = Collections.emptyList();
- String url = GithubCreateGistAction.createGist(myProject, myGitHubSettings.getAuthData(), expected, true, GIST_DESCRIPTION, null);
+ String url = GithubCreateGistAction.createGist(myProject, getAuthDataHolder(), myIndicator, expected, true, GIST_DESCRIPTION, null);
assertNull("Gist was created", url);
checkNotification(NotificationType.WARNING, "Can't create Gist", "Can't create empty gist");
}
public void testWrongLogin() throws Throwable {
- registerDefaultLoginDialogHandler();
+ registerCancelingLoginDialogHandler();
List<FileContent> expected = createContent();
GithubAuthData auth = myGitHubSettings.getAuthData();
GithubAuthData myAuth = GithubAuthData.createBasicAuth(auth.getHost(), myLogin1 + "some_suffix", myPassword);
- String url = GithubCreateGistAction.createGist(myProject, myAuth, expected, true, GIST_DESCRIPTION, null);
+ String url =
+ GithubCreateGistAction.createGist(myProject, new GithubAuthDataHolder(myAuth), myIndicator, expected, true, GIST_DESCRIPTION, null);
assertNull("Gist was created", url);
checkNotification(NotificationType.ERROR, "Can't create Gist", null);
}
public void testWrongPassword() throws Throwable {
- registerDefaultLoginDialogHandler();
+ registerCancelingLoginDialogHandler();
List<FileContent> expected = createContent();
GithubAuthData auth = myGitHubSettings.getAuthData();
GithubAuthData myAuth = GithubAuthData.createBasicAuth(auth.getHost(), myLogin1, myPassword + "some_suffix");
- String url = GithubCreateGistAction.createGist(myProject, myAuth, expected, true, GIST_DESCRIPTION, null);
+ String url =
+ GithubCreateGistAction.createGist(myProject, new GithubAuthDataHolder(myAuth), myIndicator, expected, true, GIST_DESCRIPTION, null);
assertNull("Gist was created", url);
checkNotification(NotificationType.ERROR, "Can't create Gist", null);
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java b/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java
index 5e785fa7de44..17a0c68781e4 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java
@@ -25,6 +25,7 @@ import org.jetbrains.plugins.github.api.GithubApiUtil;
import org.jetbrains.plugins.github.api.GithubGist;
import org.jetbrains.plugins.github.test.GithubTest;
import org.jetbrains.plugins.github.ui.GithubLoginDialog;
+import org.jetbrains.plugins.github.util.GithubAuthDataHolder;
import java.io.IOException;
import java.util.ArrayList;
@@ -51,6 +52,11 @@ public abstract class GithubCreateGistTestBase extends GithubTest {
deleteGist();
}
+ @NotNull
+ protected GithubAuthDataHolder getAuthDataHolder() {
+ return new GithubAuthDataHolder(myGitHubSettings.getAuthData());
+ }
+
protected void deleteGist() throws IOException {
if (GIST_ID != null) {
GithubApiUtil.deleteGist(myGitHubSettings.getAuthData(), GIST_ID);
@@ -133,7 +139,7 @@ public abstract class GithubCreateGistTestBase extends GithubTest {
assertTrue("Gist content differs from sample", Comparing.haveEqualElements(expected, actual));
}
- protected void registerDefaultLoginDialogHandler() {
+ protected void registerCancelingLoginDialogHandler() {
myDialogManager.registerDialogHandler(GithubLoginDialog.class, new TestDialogHandler<GithubLoginDialog>() {
@Override
public int handleDialog(GithubLoginDialog dialog) {
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubUrlUtilTest.java b/plugins/github/test/org/jetbrains/plugins/github/GithubUrlUtilTest.java
index ce187b76e1ef..636d14d149d1 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubUrlUtilTest.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubUrlUtilTest.java
@@ -90,7 +90,7 @@ public class GithubUrlUtilTest extends UsefulTestCase {
});
}
- public void testIsGithubUrl() throws Throwable {
+ public void testIsGithubUrl1() throws Throwable {
TestCase<Boolean> tests = new TestCase<Boolean>();
tests.add("http://github.com/user/repo", true);
@@ -118,13 +118,50 @@ public class GithubUrlUtilTest extends UsefulTestCase {
runTestCase(tests, new Convertor<String, Boolean>() {
@Override
public Boolean convert(String in) {
- return isGithubUrl(in, removeTrailingSlash(removeProtocolPrefix("https://github.com/")));
+ return isGithubUrl(in, "https://github.com/");
}
});
runTestCase(tests, new Convertor<String, Boolean>() {
@Override
public Boolean convert(String in) {
- return isGithubUrl(in, removeTrailingSlash(removeProtocolPrefix("http://GitHub.com")));
+ return isGithubUrl(in, "http://GitHub.com");
+ }
+ });
+ }
+
+ public void testIsGithubUrl2() throws Throwable {
+ TestCase<Boolean> tests = new TestCase<Boolean>();
+
+ tests.add("http://git.code.example.co.jp/user/repo", true);
+ tests.add("https://git.code.example.co.jp/user/repo", true);
+ tests.add("git://git.code.example.co.jp/user/repo", true);
+ tests.add("git@git.code.example.co.jp:user/repo", true);
+
+ tests.add("http://git.code.example.co/user/repo", false);
+ tests.add("http://code.example.co.jp/user/repo", false);
+
+ runTestCase(tests, new Convertor<String, Boolean>() {
+ @Override
+ public Boolean convert(String in) {
+ return isGithubUrl(in, "git.code.example.co.jp");
+ }
+ });
+ runTestCase(tests, new Convertor<String, Boolean>() {
+ @Override
+ public Boolean convert(String in) {
+ return isGithubUrl(in, "http://git.code.example.co.jp");
+ }
+ });
+ runTestCase(tests, new Convertor<String, Boolean>() {
+ @Override
+ public Boolean convert(String in) {
+ return isGithubUrl(in, "https://git.code.example.co.jp/github/server");
+ }
+ });
+ runTestCase(tests, new Convertor<String, Boolean>() {
+ @Override
+ public Boolean convert(String in) {
+ return isGithubUrl(in, "git.code.example.co.jp/api");
}
});
}
diff --git a/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java b/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java
index 2c9496e9a27e..1f7635d35601 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java
@@ -210,7 +210,7 @@ public abstract class GithubTest extends UsefulTestCase {
myAuth = GithubAuthData.createBasicAuth(host, login1, password);
myGitHubSettings = GithubSettings.getInstance();
- myGitHubSettings.setCredentials(myHost, myAuth, false);
+ myGitHubSettings.setAuthData(myAuth, false);
myDialogManager = (TestDialogManager)ServiceManager.getService(DialogManager.class);
myNotificator = (TestNotificator)ServiceManager.getService(myProject, Notificator.class);
diff --git a/plugins/google-app-engine/jps-plugin/google-app-engine-jps-plugin.iml b/plugins/google-app-engine/jps-plugin/google-app-engine-jps-plugin.iml
index e471a6a62370..313b6317ce0a 100644
--- a/plugins/google-app-engine/jps-plugin/google-app-engine-jps-plugin.iml
+++ b/plugins/google-app-engine/jps-plugin/google-app-engine-jps-plugin.iml
@@ -13,6 +13,7 @@
<orderEntry type="module" module-name="jps-model-serialization" />
<orderEntry type="module" module-name="jps-model-impl" scope="TEST" />
<orderEntry type="module" module-name="appEngine-runtime" />
+ <orderEntry type="module" module-name="jps-serialization-tests" scope="TEST" />
</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 d8d32974aef4..af83972c7ec5 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
@@ -19,14 +19,18 @@ package org.jetbrains.jps.incremental.groovy;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
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.ContainerUtilRt;
+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;
import org.jetbrains.jps.builders.BuildRootIndex;
@@ -63,6 +67,7 @@ import java.util.concurrent.Future;
* Date: 10/25/11
*/
public class GroovyBuilder extends ModuleLevelBuilder {
+ private static final int ourOptimizeThreshold = Integer.parseInt(System.getProperty("groovyc.optimized.class.loading.threshold", "10"));
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.groovy.GroovyBuilder");
private static final Key<Boolean> CHUNK_REBUILD_ORDERED = Key.create("CHUNK_REBUILD_ORDERED");
private static final Key<Map<String, String>> STUB_TO_SRC = Key.create("STUB_TO_SRC");
@@ -86,6 +91,7 @@ public class GroovyBuilder extends ModuleLevelBuilder {
ModuleChunk chunk,
DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
OutputConsumer outputConsumer) throws ProjectBuildException {
+ long start = 0;
try {
JpsGroovySettings settings = JpsGroovySettings.getSettings(context.getProjectDescriptor().getProject());
@@ -102,8 +108,10 @@ public class GroovyBuilder extends ModuleLevelBuilder {
return ExitCode.ABORT;
}
+ start = System.currentTimeMillis();
final Set<String> toCompilePaths = getPathsToCompile(toCompile);
-
+ boolean optimizeClassLoading = ourOptimizeThreshold != 0 && toCompilePaths.size() >= ourOptimizeThreshold;
+
Map<String, String> class2Src = buildClassToSourceMap(chunk, context, toCompilePaths, finalOutputs);
final String encoding = context.getProjectDescriptor().getEncodingConfiguration().getPreferredModuleChunkEncoding(chunk);
@@ -117,10 +125,18 @@ public class GroovyBuilder extends ModuleLevelBuilder {
String compilerOutput = generationOutputs.get(chunk.representativeTarget());
String finalOutput = FileUtil.toSystemDependentName(finalOutputs.get(chunk.representativeTarget()));
+
+ Collection<String> classpath = generateClasspath(context, chunk);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Optimized class loading: " + optimizeClassLoading);
+ LOG.debug("Groovyc classpath: " + classpath);
+ }
+
final File tempFile = GroovycOSProcessHandler.fillFileWithGroovycParameters(
- compilerOutput, toCompilePaths, finalOutput, class2Src, encoding, patchers
+ compilerOutput, toCompilePaths, finalOutput, class2Src, encoding, patchers,
+ optimizeClassLoading ? StringUtil.join(classpath, File.pathSeparator) : ""
);
- final GroovycOSProcessHandler handler = runGroovyc(context, chunk, tempFile, settings);
+ final GroovycOSProcessHandler handler = runGroovyc(context, chunk, tempFile, settings, classpath, optimizeClassLoading);
Map<ModuleBuildTarget, Collection<GroovycOSProcessHandler.OutputItem>>
compiled = processCompiledFiles(context, chunk, generationOutputs, compilerOutput, handler);
@@ -147,8 +163,11 @@ public class GroovyBuilder extends ModuleLevelBuilder {
throw new ProjectBuildException(e);
}
finally {
+ if (start > 0 && LOG.isDebugEnabled()) {
+ LOG.debug(myBuilderName + " took " + (System.currentTimeMillis() - start) + " on " + chunk.getName());
+ }
if (!myForStubs) {
- FILES_MARKED_DIRTY_FOR_NEXT_ROUND.set(context, null);
+ FILES_MARKED_DIRTY_FOR_NEXT_ROUND.set(context, null);
}
}
}
@@ -169,15 +188,24 @@ public class GroovyBuilder extends ModuleLevelBuilder {
}
private GroovycOSProcessHandler runGroovyc(final CompileContext context,
- ModuleChunk chunk,
+ final ModuleChunk chunk,
File tempFile,
- final JpsGroovySettings settings) throws IOException {
- ArrayList<String> classpath = new ArrayList<String>(generateClasspath(context, chunk));
- if (LOG.isDebugEnabled()) {
- LOG.debug("Groovyc classpath: " + classpath);
+ final JpsGroovySettings settings,
+ Collection<String> compilationClassPath,
+ boolean optimizeClassLoading) throws IOException {
+ List<String> classpath = new ArrayList<String>();
+ if (optimizeClassLoading) {
+ classpath.add(getGroovyRtRoot().getPath());
+ classpath.add(ClasspathBootstrap.getResourcePath(Function.class));
+ classpath.add(ClasspathBootstrap.getResourcePath(UrlClassLoader.class));
+ classpath.add(ClasspathBootstrap.getResourceFile(THashMap.class).getPath());
+ } else {
+ classpath.addAll(compilationClassPath);
}
- List<String> programParams = ContainerUtilRt.newArrayList(myForStubs ? "stubs" : "groovyc", tempFile.getPath());
+ List<String> programParams = ContainerUtilRt.newArrayList(optimizeClassLoading ? GroovyRtConstants.OPTIMIZE : "do_not_optimize",
+ myForStubs ? "stubs" : "groovyc",
+ tempFile.getPath());
if (settings.invokeDynamic) {
programParams.add("--indy");
}
@@ -203,7 +231,7 @@ public class GroovyBuilder extends ModuleLevelBuilder {
final Process process = Runtime.getRuntime().exec(ArrayUtil.toStringArray(cmd));
final Consumer<String> updater = new Consumer<String>() {
public void consume(String s) {
- context.processMessage(new ProgressMessage(s));
+ context.processMessage(new ProgressMessage(s + " [" + chunk.getPresentableShortName() + "]"));
}
};
final GroovycOSProcessHandler handler = new GroovycOSProcessHandler(process, updater) {
@@ -403,7 +431,7 @@ public class GroovyBuilder extends ModuleLevelBuilder {
callback.associate(outputPath, sourcePath, new ClassReader(FileUtil.loadFileBytes(outputFile)));
}
catch (Throwable e) {
- // need this to make sure that unexpected errors in, for example, ASM will not ruin the compilation
+ // need this to make sure that unexpected errors in, for example, ASM will not ruin the compilation
final String message = "Class dependency information may be incomplete! Error parsing generated class " + item.outputPath;
LOG.info(message, e);
context.processMessage(new CompilerMessage(
diff --git a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovycOSProcessHandler.java b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovycOSProcessHandler.java
index 9a5a3d0bce25..a03067d99e61 100644
--- a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovycOSProcessHandler.java
+++ b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovycOSProcessHandler.java
@@ -219,10 +219,12 @@ public class GroovycOSProcessHandler extends BaseOSProcessHandler {
if (unparsedBuffer.length() != 0) {
String msg = unparsedBuffer.toString();
if (msg.contains(GroovyRtConstants.NO_GROOVY)) {
- msg = "Cannot compile Groovy files: no Groovy library is defined for module '" + moduleName + "'";
+ messages.add(new CompilerMessage("", BuildMessage.Kind.ERROR,
+ "Cannot compile Groovy files: no Groovy library is defined for module '" + moduleName + "'"));
+ } else {
+ messages.add(new CompilerMessage("Groovyc", BuildMessage.Kind.INFO, msg));
}
- messages.add(new CompilerMessage("Groovyc", BuildMessage.Kind.INFO, msg));
}
final int exitValue = getProcess().exitValue();
@@ -245,11 +247,17 @@ public class GroovycOSProcessHandler extends BaseOSProcessHandler {
public static File fillFileWithGroovycParameters(final String outputDir,
final Collection<String> changedSources,
String finalOutput,
- Map<String, String> class2Src, @Nullable final String encoding, List<String> patchers) throws IOException {
+ Map<String, String> class2Src,
+ @Nullable final String encoding,
+ List<String> patchers,
+ String classpath) throws IOException {
File tempFile = FileUtil.createTempFile("ideaGroovyToCompile", ".txt", true);
final Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tempFile)));
try {
+ writer.write(classpath);
+ writer.write("\n");
+
for (String file : changedSources) {
writer.write(GroovyRtConstants.SRC_FILE + "\n");
writer.write(file);
diff --git a/plugins/groovy/rt-constants/src/org/jetbrains/groovy/compiler/rt/GroovyRtConstants.java b/plugins/groovy/rt-constants/src/org/jetbrains/groovy/compiler/rt/GroovyRtConstants.java
index d146db0caa35..37583ddc96e4 100644
--- a/plugins/groovy/rt-constants/src/org/jetbrains/groovy/compiler/rt/GroovyRtConstants.java
+++ b/plugins/groovy/rt-constants/src/org/jetbrains/groovy/compiler/rt/GroovyRtConstants.java
@@ -36,4 +36,5 @@ public class GroovyRtConstants {
public static final String PRESENTABLE_MESSAGE = "@#$%@# Presentable:";
public static final String CLEAR_PRESENTABLE = "$@#$%^ CLEAR_PRESENTABLE";
public static final String NO_GROOVY = "Cannot compile Groovy files: no Groovy library is defined";
+ public static final String OPTIMIZE = "optimize";
}
diff --git a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/DependentGroovycRunner.java b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/DependentGroovycRunner.java
index 835c91d2d153..bb374cdfcdf4 100644
--- a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/DependentGroovycRunner.java
+++ b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/DependentGroovycRunner.java
@@ -39,7 +39,8 @@ import java.util.*;
* @author peter
*/
public class DependentGroovycRunner {
- static boolean runGroovyc(boolean forStubs, File argsFile) {
+ public static boolean runGroovyc(boolean forStubs, String argsPath) {
+ File argsFile = new File(argsPath);
final CompilerConfiguration config = new CompilerConfiguration();
config.setClasspath("");
config.setOutput(new PrintWriter(System.err));
@@ -113,8 +114,9 @@ public class DependentGroovycRunner {
stream = new FileInputStream(argsFile);
reader = new BufferedReader(new InputStreamReader(stream));
- String line;
+ reader.readLine(); // skip classpath
+ String line;
while ((line = reader.readLine()) != null) {
if (!GroovyRtConstants.SRC_FILE.equals(line)) {
break;
diff --git a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovyCompilerUtil.java b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovyCompilerUtil.java
deleted file mode 100644
index fc7a74c0ec91..000000000000
--- a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovyCompilerUtil.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2000-2008 JetBrains s.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.groovy.compiler.rt;
-
-import org.codehaus.groovy.control.CompilerConfiguration;
-
-import java.net.URL;
-import java.net.MalformedURLException;
-import java.util.List;
-import java.io.File;
-
-/**
- * @author ilyas
- */
-public class GroovyCompilerUtil {
- static URL[] convertClasspathToUrls(CompilerConfiguration compilerConfiguration) {
- try {
- return classpathAsUrls(compilerConfiguration);
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
-
- static URL[] classpathAsUrls(CompilerConfiguration compilerConfiguration) throws MalformedURLException {
- List classpath = compilerConfiguration.getClasspath();
- URL[] classpathUrls = new URL[classpath.size()];
- for (int i = 0; i < classpathUrls.length; i++) {
- String classpathEntry = (String) classpath.get(i);
- classpathUrls[i] = new File(classpathEntry).toURI().toURL();
- }
- return classpathUrls;
- }
-}
diff --git a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java
index 3d7e8eb5dd80..aaa42bca43c3 100644
--- a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java
+++ b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java
@@ -15,7 +15,16 @@
package org.jetbrains.groovy.compiler.rt;
+import com.intellij.util.lang.UrlClassLoader;
+import sun.misc.URLClassPath;
+
+import java.io.BufferedReader;
import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.*;
/**
* @author: Dmitry.Krasilschikov
@@ -57,24 +66,28 @@ public class GroovycRunner {
}
*/
- if (args.length != 2) {
- if (args.length != 3 || !"--indy".equals(args[2])) {
+ if (args.length != 3) {
+ if (args.length != 4 || !"--indy".equals(args[3])) {
System.err.println("There is no arguments for groovy compiler");
System.exit(1);
}
System.setProperty("groovy.target.indy", "true");
}
- final boolean forStubs = "stubs".equals(args[0]);
- final File argsFile = new File(args[1]);
+ final boolean optimize = GroovyRtConstants.OPTIMIZE.equals(args[0]);
+ final boolean forStubs = "stubs".equals(args[1]);
+ String argPath = args[2];
- if (!argsFile.exists()) {
+ if (!new File(argPath).exists()) {
System.err.println("Arguments file for groovy compiler not found");
System.exit(1);
}
+ ClassLoader loader = optimize ? buildMainLoader(argPath) : GroovycRunner.class.getClassLoader();
+ Thread.currentThread().setContextClassLoader(loader);
+
try {
- Class.forName("org.codehaus.groovy.control.CompilationUnit");
+ Class.forName("org.codehaus.groovy.control.CompilationUnit", true, loader);
}
catch (Throwable e) {
System.err.println(GroovyRtConstants.NO_GROOVY);
@@ -82,7 +95,9 @@ public class GroovycRunner {
}
try {
- DependentGroovycRunner.runGroovyc(forStubs, argsFile);
+ Class<?> aClass = Class.forName("org.jetbrains.groovy.compiler.rt.DependentGroovycRunner", true, loader);
+ Method method = aClass.getDeclaredMethod("runGroovyc", boolean.class, String.class);
+ method.invoke(null, forStubs, argPath);
}
catch (Throwable e) {
e.printStackTrace();
@@ -102,4 +117,43 @@ public class GroovycRunner {
}
*/
}
+
+ private static ClassLoader buildMainLoader(String argsPath) {
+ Set<URL> bootstrapUrls = new HashSet<URL>();
+ try {
+ Method method = ClassLoader.class.getDeclaredMethod("getBootstrapClassPath");
+ method.setAccessible(true);
+ URLClassPath ucp = (URLClassPath)method.invoke(null);
+ Collections.addAll(bootstrapUrls, ucp.getURLs());
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ final List<URL> urls = new ArrayList<URL>();
+ try {
+ //noinspection IOResourceOpenedButNotSafelyClosed
+ BufferedReader reader = new BufferedReader(new FileReader(argsPath));
+ String classpath = reader.readLine();
+ for (String s : classpath.split(File.pathSeparator)) {
+ URL url = new File(s).toURI().toURL();
+ if (!bootstrapUrls.contains(url)) {
+ urls.add(url);
+ }
+ }
+ reader.close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ final ClassLoader[] ref = new ClassLoader[1];
+ new Runnable() {
+ public void run() {
+ ref[0] = UrlClassLoader.build().urls(urls).useCache().get();
+ }
+ }.run();
+ return ref[0];
+ }
}
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 45fde1fd9fcc..c7965371c064 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -79,6 +79,7 @@
<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">
@@ -150,7 +151,30 @@
<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"/>
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
index dee417b1a58a..4f7ebf4bbcd4 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
@@ -168,9 +168,12 @@ public class GroovyAnnotator extends GroovyElementVisitor {
@Override
public void visitNamedArgument(GrNamedArgument argument) {
- final PsiElement parent = argument.getParent().getParent();
- if (parent instanceof GrIndexProperty) {
- myHolder.createErrorAnnotation(argument, GroovyBundle.message("named.arguments.are.not.allowed.inside.index.operations"));
+ PsiElement parent = argument.getParent();
+ if (parent instanceof GrArgumentList) {
+ final PsiElement pparent = parent.getParent();
+ if (pparent instanceof GrIndexProperty) {
+ myHolder.createErrorAnnotation(argument, GroovyBundle.message("named.arguments.are.not.allowed.inside.index.operations"));
+ }
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateParameterFromUsageFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateParameterFromUsageFix.java
index a99f62d9b2c9..4ab96f047175 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateParameterFromUsageFix.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateParameterFromUsageFix.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.
@@ -49,7 +49,6 @@ import org.jetbrains.plugins.groovy.refactoring.ui.MethodOrClosureScopeChooser;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.Set;
/**
* @author Max Medvedev
@@ -138,9 +137,9 @@ public class CreateParameterFromUsageFix extends Intention implements MethodOrCl
if (project.isDisposed()) return;
final String name = ref.getReferenceName();
- final Set<PsiType> types = GroovyExpectedTypesProvider.getDefaultExpectedTypes(ref);
+ final List<PsiType> types = GroovyExpectedTypesProvider.getDefaultExpectedTypes(ref);
- PsiType unboxed = types.isEmpty() ? null : TypesUtil.unboxPrimitiveTypeWrapper(types.iterator().next());
+ PsiType unboxed = types.isEmpty() ? null : TypesUtil.unboxPrimitiveTypeWrapper(types.get(0));
@NotNull final PsiType type = unboxed != null ? unboxed : PsiType.getJavaLangObject(ref.getManager(), ref.getResolveScope());
if (method instanceof GrMethod) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties
index 3d658f098b0e..c19311d13dec 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionBundle.properties
@@ -109,4 +109,6 @@ change.lvalue.type=Change variable ''{0}'' type to ''{1}''
replace.qualified.name.with.import=Replace qualified name with import
highlight.assignments.from.void=Highlight assignments from void type
comments.count.as.content=Comments count as content
-ignore.when.catch.parameter.is.named.ignore.or.ignored=Ignore when catch parameter is named ignore or ignored \ No newline at end of file
+ignore.when.catch.parameter.is.named.ignore.or.ignored=Ignore when catch parameter is named ignore or ignored
+no.applicable.signature.found=No applicable signature found
+expected.type.0=Expected {0} \ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java
index 970b39123c7c..b0d47a0552b3 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java
@@ -24,6 +24,7 @@ import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
@@ -70,8 +71,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.*;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
@@ -79,6 +82,7 @@ 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.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParameterEnhancer;
+import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParamsEnhancer;
import org.jetbrains.plugins.groovy.lang.psi.util.*;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
@@ -242,7 +246,6 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
@Override
public void visitReturnStatement(GrReturnStatement returnStatement) {
- super.visitReturnStatement(returnStatement);
final GrExpression value = returnStatement.getReturnValue();
if (value == null || isNewInstanceInitialingByTuple(value)) return;
@@ -254,7 +257,6 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
@Override
public void visitExpression(GrExpression expression) {
- super.visitExpression(expression);
if (PsiUtil.isExpressionStatement(expression)) {
final PsiType returnType = PsiImplUtil.inferReturnType(expression);
final GrControlFlowOwner flowOwner = ControlFlowUtils.findControlFlowOwner(expression);
@@ -274,8 +276,6 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
@Override
public void visitAssignmentExpression(GrAssignmentExpression assignment) {
- super.visitAssignmentExpression(assignment);
-
GrExpression lValue = assignment.getLValue();
if (lValue instanceof GrIndexProperty) return;
if (!PsiUtil.mightBeLValue(lValue)) return;
@@ -363,8 +363,6 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
@Override
public void visitVariable(GrVariable variable) {
- super.visitVariable(variable);
-
PsiType varType = variable.getType();
PsiElement parent = variable.getParent();
@@ -430,7 +428,6 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
@Override
public void visitNewExpression(GrNewExpression newExpression) {
- super.visitNewExpression(newExpression);
if (newExpression.getArrayCount() > 0) return;
GrCodeReferenceElement refElement = newExpression.getReferenceElement();
@@ -502,7 +499,6 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
@Override
public void visitListOrMap(GrListOrMap listOrMap) {
- super.visitListOrMap(listOrMap);
final PsiReference reference = listOrMap.getReference();
if (!(reference instanceof LiteralConstructorReference)) return;
@@ -515,7 +511,6 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
@Override
public void visitThrowStatement(GrThrowStatement throwStatement) {
- super.visitThrowStatement(throwStatement);
final GrExpression exception = throwStatement.getException();
if (exception != null) {
@@ -557,7 +552,6 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
@Override
public void visitConstructorInvocation(GrConstructorInvocation invocation) {
- super.visitConstructorInvocation(invocation);
GrConstructorInvocationInfo info = new GrConstructorInvocationInfo(invocation);
checkConstructorCall(info);
checkNamedArgumentsType(info);
@@ -565,8 +559,6 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
@Override
public void visitIndexProperty(GrIndexProperty expression) {
- super.visitIndexProperty(expression);
-
checkIndexProperty(new GrIndexPropertyInfo(expression));
}
@@ -651,25 +643,21 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
@Override
public void visitMethodCallExpression(GrMethodCallExpression methodCallExpression) {
- super.visitMethodCallExpression(methodCallExpression);
checkMethodCall(new GrMethodCallInfo(methodCallExpression));
}
@Override
public void visitApplicationStatement(GrApplicationStatement applicationStatement) {
- super.visitApplicationStatement(applicationStatement);
checkMethodCall(new GrMethodCallInfo(applicationStatement));
}
@Override
public void visitBinaryExpression(GrBinaryExpression binary) {
- super.visitBinaryExpression(binary);
checkOperator(new GrBinaryExprInfo(binary));
}
@Override
public void visitEnumConstant(GrEnumConstant enumConstant) {
- super.visitEnumConstant(enumConstant);
GrEnumConstantInfo info = new GrEnumConstantInfo(enumConstant);
checkConstructorCall(info);
checkNamedArgumentsType(info);
@@ -710,6 +698,60 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
}
}
+ @Override
+ public void visitParameterList(final GrParameterList parameterList) {
+ PsiElement parent = parameterList.getParent();
+ if (parent instanceof GrClosableBlock) {
+
+ GrParameter[] parameters = parameterList.getParameters();
+ if (parameters.length > 0) {
+ List<PsiType[]> signatures = ClosureParamsEnhancer.findFittingSignatures((GrClosableBlock)parent);
+ final List<PsiType> paramTypes = ContainerUtil.map(parameters, new Function<GrParameter, PsiType>() {
+ @Override
+ public PsiType fun(GrParameter parameter) {
+ return parameter.getType();
+ }
+ });
+
+ if (signatures.size() > 1) {
+ PsiType[] fittingSignature = ContainerUtil.find(signatures, new Condition<PsiType[]>() {
+ @Override
+ public boolean value(PsiType[] types) {
+ for (int i = 0; i < types.length; i++) {
+ if (!typesAreEqual(types[i], paramTypes.get(i), parameterList)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ });
+
+ if (fittingSignature == null) {
+ registerError(parameterList, GroovyInspectionBundle.message("no.applicable.signature.found"));
+ }
+ }
+ else if (signatures.size() == 1) {
+ PsiType[] types = signatures.get(0);
+ for (int i = 0; i < types.length; i++) {
+ GrTypeElement typeElement = parameters[i].getTypeElementGroovy();
+ if (typeElement == null) continue;
+ PsiType expected = types[i];
+ PsiType actual = paramTypes.get(i);
+ if (!typesAreEqual(expected, actual, parameterList)) {
+ registerError(typeElement, GroovyInspectionBundle.message("expected.type.0", expected.getPresentableText()));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static boolean typesAreEqual(@NotNull PsiType expected, @NotNull PsiType actual, @NotNull PsiElement context) {
+ return TypesUtil.isAssignableByMethodCallConversion(expected, actual, context) &&
+ TypesUtil.isAssignableByMethodCallConversion(actual, expected, context);
+ }
+
+
/**
* checks only children of e
*/
@@ -1020,6 +1062,11 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
private void highlightUnknownArgs(@NotNull CallInfo info) {
registerError(info.getElementToHighlight(), GroovyBundle.message("cannot.infer.argument.types"), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.WEAK_WARNING);
}
+
+ @Override
+ public void visitElement(GroovyPsiElement element) {
+ //do nothing
+ }
}
@Nullable
@@ -1108,12 +1155,6 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
Object... args) {
registerError(location, (String)args[0], LocalQuickFix.EMPTY_ARRAY, highlightType);
}
-
-
- @Override
- public void visitElement(GroovyPsiElement element) {
- //do nothing
- }
}
private static final ThreadLocal<AnnotatingVisitor> visitor = new ThreadLocal<AnnotatingVisitor>() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GrReassignedInClosureLocalVarInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GrReassignedInClosureLocalVarInspection.java
index 82a688f9bd89..400c0a366970 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GrReassignedInClosureLocalVarInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GrReassignedInClosureLocalVarInspection.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,12 +21,16 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.codeInsight.GrReassignedLocalVarsChecker;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
+import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
import org.jetbrains.plugins.groovy.lang.psi.GrNamedElement;
-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.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
+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.refactoring.GroovyRefactoringUtil;
@@ -66,18 +70,38 @@ public class GrReassignedInClosureLocalVarInspection extends BaseInspection {
final PsiElement resolved = referenceExpression.resolve();
if (!GroovyRefactoringUtil.isLocalVariable(resolved)) return;
- if (isOtherTypeOrDifferent(referenceExpression, (GrVariable)resolved) ) {
- final String message = message("local.var.0.is.reassigned", ((GrNamedElement)resolved).getName());
+ final PsiType checked = GrReassignedLocalVarsChecker.getReassignedVarType(referenceExpression, false);
+ if (checked == null) return;
+
+ final GrControlFlowOwner varFlowOwner = ControlFlowUtils.findControlFlowOwner(resolved);
+ final GrControlFlowOwner refFlorOwner = ControlFlowUtils.findControlFlowOwner(referenceExpression);
+ if (isOtherScopeAndType(referenceExpression, checked, varFlowOwner, refFlorOwner)) {
+ String flowDescription = getFlowDescription(refFlorOwner);
+ final String message = message("local.var.0.is.reassigned", ((GrNamedElement)resolved).getName(), flowDescription);
registerError(referenceExpression, message, LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
}
};
}
- private static boolean isOtherTypeOrDifferent(@NotNull GrReferenceExpression referenceExpression, GrVariable resolved) {
- if (ControlFlowUtils.findControlFlowOwner(referenceExpression) != ControlFlowUtils.findControlFlowOwner(resolved)) return true;
+ private static boolean isOtherScopeAndType(GrReferenceExpression referenceExpression,
+ PsiType checked,
+ GrControlFlowOwner varFlowOwner,
+ GrControlFlowOwner refFlorOwner) {
+ return varFlowOwner != refFlorOwner && !TypesUtil.isAssignable(referenceExpression.getType(), checked, referenceExpression);
+ }
- final PsiType currentType = referenceExpression.getType();
- return currentType != null && currentType != PsiType.NULL && !ControlFlowUtils.findAccess(resolved, referenceExpression, false, true).isEmpty();
+ private static String getFlowDescription(GrControlFlowOwner refFlorOwner) {
+ String flowDescription;
+ if (refFlorOwner instanceof GrClosableBlock) {
+ flowDescription = message("closure");
+ }
+ else if (refFlorOwner instanceof GrAnonymousClassDefinition) {
+ flowDescription = message("anonymous.class");
+ }
+ else {
+ flowDescription = message("other.scope");
+ }
+ return flowDescription;
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java
index 31a97407fd13..78e3886b7842 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/noReturnMethod/MissingReturnInspection.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.
@@ -49,7 +49,6 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
/**
* @author ven
@@ -125,9 +124,7 @@ public class MissingReturnInspection extends GroovySuppressableInspectionTool {
}
}
else {
- final Set<PsiType> expectedTypes = GroovyExpectedTypesProvider.getDefaultExpectedTypes(closure);
-
- for (PsiType expectedType : expectedTypes) {
+ for (PsiType expectedType : GroovyExpectedTypesProvider.getDefaultExpectedTypes(closure)) {
if (TypesUtil.isPsiClassTypeToClosure(expectedType)) {
PsiType[] parameters = ((PsiClassType)expectedType).getParameters();
if (parameters.length == 1) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GroovyUntypedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GroovyUntypedAccessInspection.java
index d0b051e31d60..f4b380bd966f 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GroovyUntypedAccessInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GroovyUntypedAccessInspection.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 org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
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.util.PsiUtil;
import static org.jetbrains.plugins.groovy.annotator.GrHighlightUtil.isDeclarationAssignment;
@@ -35,8 +36,37 @@ import static org.jetbrains.plugins.groovy.annotator.GrHighlightUtil.isDeclarati
*/
public class GroovyUntypedAccessInspection extends BaseInspection {
+ @NotNull
protected BaseInspectionVisitor buildVisitor() {
- return new Visitor();
+ return new BaseInspectionVisitor() {
+ @Override
+ public void visitReferenceExpression(GrReferenceExpression refExpr) {
+ super.visitReferenceExpression(refExpr);
+
+ if (PsiUtil.isThisOrSuperRef(refExpr)) return;
+
+ GroovyResolveResult resolveResult = refExpr.advancedResolve();
+
+ PsiElement resolved = resolveResult.getElement();
+ if (resolved != null) {
+ if (isDeclarationAssignment(refExpr) || resolved instanceof PsiPackage) return;
+ }
+ else {
+ GrExpression qualifier = refExpr.getQualifierExpression();
+ if (qualifier == null && isDeclarationAssignment(refExpr)) return;
+ }
+
+ final PsiType refExprType = refExpr.getType();
+ if (refExprType == null) {
+ if (resolved != null) {
+ registerError(refExpr);
+ }
+ }
+ else if (refExprType instanceof PsiClassType && ((PsiClassType)refExprType).resolve() == null) {
+ registerError(refExpr);
+ }
+ }
+ };
}
@Nls
@@ -55,31 +85,4 @@ public class GroovyUntypedAccessInspection extends BaseInspection {
protected String buildErrorString(Object... args) {
return "Cannot determine type of '#ref'";
}
-
- private static class Visitor extends BaseInspectionVisitor {
- @Override
- public void visitReferenceExpression(GrReferenceExpression refExpr) {
- super.visitReferenceExpression(refExpr);
- GroovyResolveResult resolveResult = refExpr.advancedResolve();
-
- PsiElement resolved = resolveResult.getElement();
- if (resolved != null) {
- if (isDeclarationAssignment(refExpr) || resolved instanceof PsiPackage) return;
- }
- else {
- GrExpression qualifier = refExpr.getQualifierExpression();
- if (qualifier == null && isDeclarationAssignment(refExpr)) return;
- }
-
- final PsiType refExprType = refExpr.getType();
- if (refExprType == null) {
- if (resolved != null) {
- registerError(refExpr);
- }
- }
- else if (refExprType instanceof PsiClassType && ((PsiClassType)refExprType).resolve() == null) {
- registerError(refExpr);
- }
- }
- }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java
index 69450a8460f4..505d88b0e4dc 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java
@@ -194,7 +194,7 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
try {
fileWithParameters = GroovycOSProcessHandler
.fillFileWithGroovycParameters(outputDir.getPath(), paths2Compile, FileUtil.toSystemDependentName(finalOutputDir.getPath()),
- class2Src, encoding, patchers);
+ class2Src, encoding, patchers, "");
}
catch (IOException e) {
LOG.info(e);
@@ -202,6 +202,7 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
return;
}
+ parameters.getProgramParametersList().add("do_not_optimize");
parameters.getProgramParametersList().add(forStubs ? "stubs" : "groovyc");
parameters.getProgramParametersList().add(fileWithParameters.getPath());
if (compilerConfiguration.isInvokeDynamic()) {
@@ -253,7 +254,7 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
if (sourceVirtualFile == null) {
continue;
}
-
+
if (indicator != null) {
indicator.setText2(sourceVirtualFile.getName());
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.java
index 8f9958b2a024..5470ed0490d9 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.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.
@@ -129,6 +129,8 @@ public class CustomMembersGenerator extends GroovyObjectSupport implements GdslM
Methods to add new behavior
*********************************************************** */
public void property(Map<Object, Object> args) {
+ if (args == null) return;
+
String name = (String)args.get("name");
Object type = args.get("type");
Object doc = args.get("doc");
@@ -156,6 +158,8 @@ public class CustomMembersGenerator extends GroovyObjectSupport implements GdslM
}
public void constructor(Map<Object, Object> args) {
+ if (args == null) return;
+
args.put("constructor", true);
method(args);
}
@@ -190,8 +194,7 @@ public class CustomMembersGenerator extends GroovyObjectSupport implements GdslM
ContainerUtil.map(argTypes, new Function<PsiType, Object>() {
@Override
public Object fun(PsiType type) {
- String canonical = type.getCanonicalText();
- return canonical != null ? canonical : type.getPresentableText();
+ return type.getCanonicalText();
}
}, types);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java
index 82cfe11991df..b852cd2159c1 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java
@@ -28,6 +28,7 @@ import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.util.io.FileUtil;
@@ -131,11 +132,13 @@ public class GroovyDslFileIndex extends ScalarIndexExtension<String> {
return myDataIndexer;
}
+ @NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return myKeyDescriptor;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new MyInputFilter();
@@ -438,7 +441,7 @@ public class GroovyDslFileIndex extends ScalarIndexExtension<String> {
@Override
public Result<List<GroovyDslScript>> compute() {
if (ourGdslStopped) {
- return Result.create(Collections.<GroovyDslScript>emptyList(), Collections.emptyList());
+ return Result.create(Collections.<GroovyDslScript>emptyList(), ModificationTracker.NEVER_CHANGED);
}
int count = 0;
@@ -513,7 +516,7 @@ public class GroovyDslFileIndex extends ScalarIndexExtension<String> {
}
@Override
- public boolean acceptInput(final VirtualFile file) {
+ public boolean acceptInput(@NotNull final VirtualFile file) {
return "gdsl".equals(file.getExtension());
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java
index bba144184a7a..8a98eeff03ea 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java
@@ -405,7 +405,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
PsiElement psi = child.getPsi();
if (psi instanceof GrLabeledStatement) {
alignGroup(currentGroup, spock, classLevel);
- currentGroup = ContainerUtil.newArrayList(/*(GrStatement)psi*/);
+ currentGroup = ContainerUtil.newArrayList();
spock = true;
}
else if (currentGroup != null && spock && isTablePart(psi)) {
@@ -428,6 +428,10 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
currentGroup = null;
}
}
+
+ if (currentGroup != null) {
+ alignGroup(currentGroup, spock, classLevel);
+ }
}
private boolean shouldSkip(boolean classLevel, PsiElement psi) {
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 4d1f239101b6..c9f6f98c3132 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
@@ -287,8 +287,7 @@ public class GroovySmartCompletionContributor extends CompletionContributor {
placeToInferType = (GrExpression)expression.getParent();
}
- final Set<PsiType> types = GroovyExpectedTypesProvider.getDefaultExpectedTypes(placeToInferType);
- for (PsiType type : types) {
+ for (PsiType type : GroovyExpectedTypesProvider.getDefaultExpectedTypes(placeToInferType)) {
if (type instanceof PsiArrayType) {
final PsiType _type = GenericsUtil.eliminateWildcards(type);
final LookupItem item = PsiTypeLookupItem.createLookupItem(_type, place, PsiTypeLookupItem.isDiamond(_type), ChooseTypeExpression.IMPORT_FIXER);
@@ -307,7 +306,7 @@ public class GroovySmartCompletionContributor extends CompletionContributor {
final List<PsiClassType> expectedClassTypes = new SmartList<PsiClassType>();
- for (PsiType psiType : types) {
+ for (PsiType psiType : GroovyExpectedTypesProvider.getDefaultExpectedTypes(placeToInferType)) {
if (psiType instanceof PsiClassType) {
PsiType type = GenericsUtil.eliminateWildcards(JavaCompletionUtil.originalize(psiType));
final PsiClassType classType = (PsiClassType)type;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java
index 10e5c0babb0d..e2e36d143e84 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parameterInfo/GroovyParameterInfoHandler.java
@@ -26,7 +26,6 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.hash.HashSet;
import com.intellij.util.text.CharArrayUtil;
-import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.documentation.GroovyPresentationUtil;
@@ -387,11 +386,11 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc
for (int j = 0; j < numParams; j++) {
PsiParameter param = params[j];
- int startOffset = XmlStringUtil.escapeString(buffer.toString()).length();
+ int startOffset = buffer.length();
appendParameterText(param, substitutor, buffer);
- int endOffset = XmlStringUtil.escapeString(buffer.toString()).length();
+ int endOffset = buffer.length();
if (j < numParams - 1) {
buffer.append(", ");
@@ -420,7 +419,7 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc
for (int i = 0; i < parameters.length; i++) {
if (i > 0) buffer.append(", ");
- int startOffset = XmlStringUtil.escapeString(buffer.toString()).length();
+ int startOffset = buffer.length();
final PsiType psiType = parameters[i].getType();
if (psiType == null) {
buffer.append("def");
@@ -430,7 +429,7 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc
}
buffer.append(' ').append(parameters[i].getName() != null ? parameters[i].getName() : "<unknown>");
- int endOffset = XmlStringUtil.escapeString(buffer.toString()).length();
+ int endOffset = buffer.length();
if (context.isUIComponentEnabled() &&
(i == currentParameter || (i == parameters.length - 1 && ((GrClosureSignature)element).isVarargs() && currentParameter >= parameters.length))) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrField.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrField.java
index 0946bd525ae6..6e3ea04a0805 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrField.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrField.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,7 +41,5 @@ public interface GrField extends GrVariable, GrMember, PsiField, GrTopLevelDefin
@NotNull
Map<String, NamedArgumentDescriptor> getNamedParameters();
-
- void clearCaches();
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java
index 09ce7cc83ea9..1d541a0b83c2 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java
@@ -22,6 +22,7 @@ import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -52,14 +53,15 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
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.signatures.GrClosureSignatureUtil;
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.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*;
@@ -97,12 +99,14 @@ public class GroovyExpectedTypesProvider {
});
}
- public static Set<PsiType> getDefaultExpectedTypes(@NotNull GrExpression element) {
- final LinkedHashSet<PsiType> result = new LinkedHashSet<PsiType>();
- for (TypeConstraint constraint : calculateTypeConstraints(element)) {
- result.add(constraint.getDefaultType());
- }
- return result;
+ public static List<PsiType> getDefaultExpectedTypes(@NotNull GrExpression element) {
+ TypeConstraint[] constraints = calculateTypeConstraints(element);
+ return ContainerUtil.map(constraints, new Function<TypeConstraint, PsiType>() {
+ @Override
+ public PsiType fun(TypeConstraint constraint) {
+ return constraint.getDefaultType();
+ }
+ });
}
private static class MyCalculator extends GroovyElementVisitor {
@@ -176,8 +180,8 @@ public class GroovyExpectedTypesProvider {
final GrClosableBlock[] closureArgs = methodCall.getClosureArguments();
if (ArrayUtil.contains(myExpression, closureArgs)) {
final GrArgumentList argumentList = methodCall.getArgumentList();
- final GrNamedArgument[] namedArgs = argumentList == null ? GrNamedArgument.EMPTY_ARRAY : argumentList.getNamedArguments();
- final GrExpression[] expressionArgs = argumentList == null ? GrExpression.EMPTY_ARRAY : argumentList.getExpressionArguments();
+ final GrNamedArgument[] namedArgs = argumentList.getNamedArguments();
+ final GrExpression[] expressionArgs = argumentList.getExpressionArguments();
final GroovyResolveResult[] callVariants = ResolveUtil.getCallVariants(myExpression);
processCallVariants(methodCall, callVariants, namedArgs, expressionArgs, closureArgs);
}
@@ -344,18 +348,32 @@ public class GroovyExpectedTypesProvider {
@NotNull GrNamedArgument[] namedArguments,
@NotNull GrExpression[] expressionArguments,
@NotNull GrClosableBlock[] closureArguments) {
+
+ List<Pair<PsiParameter, PsiType>> expectedParams =
+ ResolveUtil.collectExpectedParamsByArg(place, variants, namedArguments, expressionArguments, closureArguments, myExpression);
+
+ collectExpectedTypeFromPossibleParams(expectedParams);
+ }
+
+ private void collectExpectedTypeFromPossibleParams(List<Pair<PsiParameter, PsiType>> expectedParams) {
List<TypeConstraint> constraints = ContainerUtil.newArrayList();
- for (GroovyResolveResult variant : variants) {
- final Map<GrExpression, Pair<PsiParameter, PsiType>> map = GrClosureSignatureUtil.mapArgumentsToParameters(
- variant, place, true, true, namedArguments, expressionArguments, closureArguments
- );
- addConstraintsFromMap(constraints, map);
+ for (Pair<PsiParameter, PsiType> pair : expectedParams) {
+ final PsiType type = pair.second;
+ if (type != null) {
+
+ constraints.add(SubtypeConstraint.create(type));
+
+ if (type instanceof PsiArrayType && pair.first.isVarArgs()) {
+ constraints.add(SubtypeConstraint.create(((PsiArrayType)type).getComponentType()));
+ }
+ }
}
if (!constraints.isEmpty()) {
myResult = constraints.toArray(new TypeConstraint[constraints.size()]);
}
}
+
@Override
public void visitBinaryExpression(GrBinaryExpression expression) {
final IElementType type = expression.getOperationTokenType();
@@ -382,7 +400,8 @@ public class GroovyExpectedTypesProvider {
}
}
else { //myExpression == right
- processCallVariants(expression, callVariants, GrNamedArgument.EMPTY_ARRAY, new GrExpression[]{myExpression}, GrClosableBlock.EMPTY_ARRAY);
+ processCallVariants(expression, callVariants, GrNamedArgument.EMPTY_ARRAY, new GrExpression[]{myExpression},
+ GrClosableBlock.EMPTY_ARRAY);
}
}
@@ -398,22 +417,6 @@ public class GroovyExpectedTypesProvider {
}
}
- private void addConstraintsFromMap(List<TypeConstraint> constraints, Map<GrExpression, Pair<PsiParameter, PsiType>> map) {
- if (map == null) return;
-
- final Pair<PsiParameter, PsiType> pair = map.get(myExpression);
- if (pair == null) return;
-
- final PsiType type = pair.second;
- if (type == null) return;
-
- constraints.add(SubtypeConstraint.create(type));
-
- if (type instanceof PsiArrayType && pair.first.isVarArgs()) {
- constraints.add(SubtypeConstraint.create(((PsiArrayType)type).getComponentType()));
- }
- }
-
public void visitAssignmentExpression(GrAssignmentExpression expression) {
GrExpression rValue = expression.getRValue();
GrExpression lValue = expression.getLValue();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrAnnotationUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrAnnotationUtil.java
index 387db8400b1e..b43ee28c1ece 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrAnnotationUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrAnnotationUtil.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,11 +15,11 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.impl;
-import com.intellij.psi.PsiAnnotation;
-import com.intellij.psi.PsiAnnotationMemberValue;
-import com.intellij.psi.PsiLiteral;
+import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
/**
* @author Max Medvedev
@@ -54,4 +54,52 @@ public class GrAnnotationUtil {
}
return null;
}
+
+ @Nullable
+ public static PsiClass inferClassAttribute(@NotNull PsiAnnotation annotation, @NotNull String attributeName) {
+ final PsiAnnotationMemberValue targetValue = annotation.findAttributeValue(attributeName);
+ if (targetValue instanceof PsiClassObjectAccessExpression) {
+ PsiType type = ((PsiClassObjectAccessExpression)targetValue).getOperand().getType();
+ if (type instanceof PsiClassType) {
+ return ((PsiClassType)type).resolve();
+ }
+ }
+ else if (targetValue instanceof GrReferenceExpression) {
+ if ("class".equals(((GrReferenceExpression)targetValue).getReferenceName())) {
+ GrExpression qualifier = ((GrReferenceExpression)targetValue).getQualifier();
+ if (qualifier instanceof GrReferenceExpression) {
+ PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
+ if (resolved instanceof PsiClass) {
+ return (PsiClass)resolved;
+ }
+ }
+ }
+ PsiElement resolved = ((GrReferenceExpression)targetValue).resolve();
+ if (resolved instanceof PsiClass) return (PsiClass)resolved;
+ }
+ return null;
+ }
+
+ @Nullable
+ public static PsiType extractClassTypeFromClassAttributeValue(PsiAnnotationMemberValue targetValue) {
+ if (targetValue instanceof PsiClassObjectAccessExpression) {
+ return ((PsiClassObjectAccessExpression)targetValue).getOperand().getType();
+ }
+ else if (targetValue instanceof GrReferenceExpression) {
+ if ("class".equals(((GrReferenceExpression)targetValue).getReferenceName())) {
+ GrExpression qualifier = ((GrReferenceExpression)targetValue).getQualifier();
+ if (qualifier instanceof GrReferenceExpression) {
+ PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
+ if (resolved instanceof PsiClass) {
+ return qualifier.getType();
+ }
+ }
+ }
+ PsiElement resolved = ((GrReferenceExpression)targetValue).resolve();
+ if (resolved instanceof PsiClass) {
+ return ((GrReferenceExpression)targetValue).getType();
+ }
+ }
+ return null;
+ }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java
index e2efdadc0445..efddced80d5a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java
@@ -56,7 +56,7 @@ public class GrClosureType extends GrLiteralClassType {
@NotNull GlobalSearchScope scope,
@NotNull JavaPsiFacade facade,
@NotNull GrSignature signature,
- @NotNull PsiType[] typeArgs) {
+ @Nullable PsiType[] typeArgs) {
super(level, scope, facade);
mySignature = signature;
@@ -132,7 +132,7 @@ public class GrClosureType extends GrLiteralClassType {
@Override
public boolean equalsToText(@NotNull @NonNls String text) {
- return text != null && text.equals(GroovyCommonClassNames.GROOVY_LANG_CLOSURE);
+ return text.equals(GroovyCommonClassNames.GROOVY_LANG_CLOSURE);
}
@Override
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrFieldImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrFieldImpl.java
index 7e852036dc04..50ccc2327086 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrFieldImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrFieldImpl.java
@@ -23,6 +23,9 @@ import com.intellij.psi.impl.ResolveScopeManager;
import com.intellij.psi.presentation.java.JavaPresentationUtil;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.stubs.IStubElementType;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.ui.LayeredIcon;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
@@ -59,8 +62,6 @@ import java.util.Map;
* Date: 25.05.2007
*/
public class GrFieldImpl extends GrVariableBaseImpl<GrFieldStub> implements GrField, StubBasedPsiElement<GrFieldStub> {
- private volatile GrAccessorMethod mySetter;
- private volatile GrAccessorMethod[] myGetters;
public GrFieldImpl(@NotNull ASTNode node) {
super(node);
@@ -188,24 +189,24 @@ public class GrFieldImpl extends GrVariableBaseImpl<GrFieldStub> implements GrFi
}
public GrAccessorMethod getSetter() {
- if (mySetter == null) {
- mySetter = GrAccessorMethodImpl.createSetterMethod(this);
- }
- return mySetter;
- }
-
- public void clearCaches() {
- mySetter = null;
- myGetters = null;
+ return CachedValuesManager.getCachedValue(this, new CachedValueProvider<GrAccessorMethod>() {
+ @Nullable
+ @Override
+ public Result<GrAccessorMethod> compute() {
+ return Result.create(GrAccessorMethodImpl.createSetterMethod(GrFieldImpl.this), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
+ }
+ });
}
@NotNull
public GrAccessorMethod[] getGetters() {
- if (myGetters == null) {
- myGetters = GrAccessorMethodImpl.createGetterMethods(this);
- }
-
- return myGetters;
+ return CachedValuesManager.getCachedValue(this, new CachedValueProvider<GrAccessorMethod[]>() {
+ @Nullable
+ @Override
+ public Result<GrAccessorMethod[]> compute() {
+ return Result.create(GrAccessorMethodImpl.createGetterMethods(GrFieldImpl.this), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
+ }
+ });
}
@NotNull
@@ -240,7 +241,8 @@ public class GrFieldImpl extends GrVariableBaseImpl<GrFieldStub> implements GrFi
}
@Nullable
- public Icon getIcon(int flags) {
+ @Override
+ protected Icon getElementIcon(@IconFlags int flags) {
Icon superIcon = JetgroovyIcons.Groovy.Field;
if (!isProperty()) return superIcon;
LayeredIcon rowIcon = new LayeredIcon(2);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
index 990876dea044..6e312234decb 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
@@ -1,6 +1,6 @@
/*
- * 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,6 @@ import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.stubs.EmptyStub;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
-import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -212,7 +211,7 @@ public class GrVariableDeclarationImpl extends GrStubElementBase<EmptyStub> impl
@Nullable
@Override
public Result<PsiReference> compute() {
- return Result.create(getReferenceInner(), PsiModificationTracker.MODIFICATION_COUNT);
+ return Result.create(getReferenceInner(), getContainingFile());
}
});
}
@@ -226,20 +225,40 @@ public class GrVariableDeclarationImpl extends GrStubElementBase<EmptyStub> impl
final GrVariable[] variables = getVariables();
if (variables.length == 0) return null;
- final PsiElement resolved = variables[0];
- return new PsiReferenceBase<GrVariableDeclaration>(this, range, true) {
- @Nullable
- @Override
- public PsiElement resolve() {
- return resolved;
- }
-
- @NotNull
- @Override
- public Object[] getVariants() {
- return EMPTY_ARRAY;
- }
- };
+ final GrVariable resolved = variables[0];
+ final PsiType inferredType = resolved.getTypeGroovy();
+ if (inferredType == null) return null;
+
+ if (inferredType instanceof PsiClassType) {
+ return new PsiReferenceBase<GrVariableDeclaration>(this, range, true) {
+ @Nullable
+ @Override
+ public PsiElement resolve() {
+ return ((PsiClassType)inferredType).resolve();
+ }
+
+ @NotNull
+ @Override
+ public Object[] getVariants() {
+ return EMPTY_ARRAY;
+ }
+ };
+ }
+ else {
+ return new PsiReferenceBase<GrVariableDeclaration>(this, range, true) {
+ @Nullable
+ @Override
+ public PsiElement resolve() {
+ return resolved;
+ }
+
+ @NotNull
+ @Override
+ public Object[] getVariants() {
+ return EMPTY_ARRAY;
+ }
+ };
+ }
}
private TextRange getRangeForReference() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
index 3119608176ff..825f4d86fdd7 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
@@ -484,10 +484,11 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
@Override
protected GrReferenceExpression bindWithQualifiedRef(@NotNull String qName) {
+ GrReferenceExpression qualifiedRef = GroovyPsiElementFactory.getInstance(getProject()).createReferenceExpressionFromText(qName);
final GrTypeArgumentList list = getTypeArgumentList();
- final String typeArgs = (list != null) ? list.getText() : "";
- final String text = qName + typeArgs;
- GrReferenceExpression qualifiedRef = GroovyPsiElementFactory.getInstance(getProject()).createReferenceExpressionFromText(text);
+ if (list != null) {
+ qualifiedRef.getNode().addChild(list.copy().getNode());
+ }
getNode().getTreeParent().replaceChild(getNode(), qualifiedRef.getNode());
return qualifiedRef;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.java
index ea18c1b94822..1c9bdc9a1b18 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionBodyBase.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.psi.StubBasedPsiElement;
import com.intellij.psi.stubs.EmptyStub;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
@@ -39,15 +40,12 @@ import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrStubElementBase;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
-import java.util.ArrayList;
import java.util.List;
/**
* @author: Dmitry.Krasilschikov, ilyas
*/
public abstract class GrTypeDefinitionBodyBase extends GrStubElementBase<EmptyStub> implements GrTypeDefinitionBody {
- private GrField[] myFields = null;
-
public GrTypeDefinitionBodyBase(@NotNull ASTNode node) {
super(node);
}
@@ -61,14 +59,6 @@ public abstract class GrTypeDefinitionBodyBase extends GrStubElementBase<EmptySt
return getParentByStub();
}
- public void subtreeChanged() {
- super.subtreeChanged();
- myFields = null;
- for (GrField field : getFields()) {
- field.clearCaches();
- }
- }
-
public abstract void accept(GroovyElementVisitor visitor);
public String toString() {
@@ -76,22 +66,18 @@ public abstract class GrTypeDefinitionBodyBase extends GrStubElementBase<EmptySt
}
public GrField[] getFields() {
- if (myFields == null) {
- GrVariableDeclaration[] declarations = getStubOrPsiChildren(GroovyElementTypes.VARIABLE_DEFINITION, GrVariableDeclaration.ARRAY_FACTORY);
- if (declarations.length == 0) return GrField.EMPTY_ARRAY;
- List<GrField> result = new ArrayList<GrField>();
- for (GrVariableDeclaration declaration : declarations) {
- GrVariable[] variables = declaration.getVariables();
- for (GrVariable variable : variables) {
- if (variable instanceof GrField) {
- result.add((GrField) variable);
- }
+ GrVariableDeclaration[] declarations = getStubOrPsiChildren(GroovyElementTypes.VARIABLE_DEFINITION, GrVariableDeclaration.ARRAY_FACTORY);
+ List<GrField> result = ContainerUtil.newArrayList();
+ for (GrVariableDeclaration declaration : declarations) {
+ GrVariable[] variables = declaration.getVariables();
+ for (GrVariable variable : variables) {
+ if (variable instanceof GrField) {
+ result.add((GrField)variable);
}
}
- myFields = result.toArray(new GrField[result.size()]);
}
- return myFields;
+ return result.toArray(new GrField[result.size()]);
}
public GrMethod[] getMethods() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java
index 0298021c626f..1c20805c3463 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.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,10 +19,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef;
import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.ItemPresentationProviders;
-import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.RecursionGuard;
-import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
@@ -31,7 +28,6 @@ import com.intellij.psi.impl.*;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.stubs.IStubElementType;
-import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
@@ -40,7 +36,6 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityIcons;
-import com.intellij.util.containers.ContainerUtil;
import icons.JetgroovyIcons;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -74,32 +69,21 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrTypeDefinitionStub;
import org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
-import org.jetbrains.plugins.groovy.lang.resolve.ast.AstTransformContributor;
import org.jetbrains.plugins.groovy.runner.GroovyRunnerUtil;
-import org.jetbrains.plugins.groovy.util.LightCacheKey;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
-import static org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil.*;
+import static org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil.isClassEquivalentTo;
/**
* @author ilyas
*/
public abstract class GrTypeDefinitionImpl extends GrStubElementBase<GrTypeDefinitionStub> implements GrTypeDefinition, StubBasedPsiElement<GrTypeDefinitionStub> {
- private static final LightCacheKey<List<GrField>> AST_TRANSFORM_FIELD = LightCacheKey.createByJavaModificationCount();
- private static final RecursionGuard ourGuard = RecursionManager.createGuard("groovyMembers");
-
- private volatile PsiClass[] myInnerClasses;
- private volatile GrMethod[] myGroovyMethods;
- private volatile PsiMethod[] myConstructors;
- private volatile GrMethod[] myCodeConstructors;
-
- Key<CachedValue<PsiMethod[]>> CACHED_METHODS = Key.create("cached.type.definition.methods");
+ private final GrTypeDefinitionMembersCache myCache = new GrTypeDefinitionMembersCache(this);
public GrTypeDefinitionImpl(@NotNull ASTNode node) {
super(node);
@@ -331,150 +315,45 @@ public abstract class GrTypeDefinitionImpl extends GrStubElementBase<GrTypeDefin
return GrClassImplUtil.findFieldByName(this, name, checkBases, false);
}
- private List<GrField> getSyntheticFields() {
- List<GrField> fields = AST_TRANSFORM_FIELD.getCachedValue(this);
- if (fields == null) {
- final RecursionGuard.StackStamp stamp = ourGuard.markStack();
- fields = AstTransformContributor.runContributorsForFields(this);
- if (stamp.mayCacheNow()) {
- fields = AST_TRANSFORM_FIELD.putCachedValue(this, fields);
- }
- }
-
- return fields;
- }
-
@NotNull
public GrField[] getFields() {
- GrField[] codeFields = getCodeFields();
-
- List<GrField> fromAstTransform = getSyntheticFields();
- if (fromAstTransform.isEmpty()) return codeFields;
-
- GrField[] res = new GrField[codeFields.length + fromAstTransform.size()];
- System.arraycopy(codeFields, 0, res, 0, codeFields.length);
-
- for (int i = 0; i < fromAstTransform.size(); i++) {
- res[codeFields.length + i] = fromAstTransform.get(i);
- }
-
- return res;
+ return myCache.getFields();
}
@NotNull
public PsiMethod[] getMethods() {
- CachedValue<PsiMethod[]> cached = getUserData(CACHED_METHODS);
- if (cached == null) {
- cached = CachedValuesManager.getManager(getProject()).createCachedValue(new CachedValueProvider<PsiMethod[]>() {
- @Override
- public Result<PsiMethod[]> compute() {
- GrTypeDefinitionBody body = getBody();
- List<PsiMethod> result = new ArrayList<PsiMethod>();
- if (body != null) {
- collectMethodsFromBody(body, result);
- }
-
- for (PsiMethod method : AstTransformContributor.runContributorsForMethods(GrTypeDefinitionImpl.this)) {
- addExpandingReflectedMethods(result, method);
- }
-
- for (GrField field : getSyntheticFields()) {
- ContainerUtil.addIfNotNull(result, field.getSetter());
- Collections.addAll(result, field.getGetters());
- }
- return Result.create(result.toArray(new PsiMethod[result.size()]), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
- }
- }, false);
- putUserData(CACHED_METHODS, cached);
- }
-
-
- return cached.getValue();
+ return myCache.getMethods();
}
@NotNull
public GrMethod[] getCodeMethods() {
- GrMethod[] cached = myGroovyMethods;
- if (cached == null) {
- RecursionGuard.StackStamp stamp = ourGuard.markStack();
- GrTypeDefinitionBody body = getBody();
- cached = body != null ? body.getMethods() : GrMethod.EMPTY_ARRAY;
- if (stamp.mayCacheNow()) {
- myGroovyMethods = cached;
- }
- }
- return cached;
+ return myCache.getCodeMethods();
}
public void subtreeChanged() {
- myInnerClasses = null;
- myConstructors = null;
- myCodeConstructors = null;
- myGroovyMethods = null;
+ myCache.dropCaches();
super.subtreeChanged();
}
@NotNull
public PsiMethod[] getConstructors() {
- PsiMethod[] cached = myConstructors;
- if (cached == null) {
- RecursionGuard.StackStamp stamp = ourGuard.markStack();
- List<PsiMethod> result = new ArrayList<PsiMethod>();
- for (final PsiMethod method : getMethods()) {
- if (method.isConstructor()) {
- addExpandingReflectedMethods(result, method);
- }
- }
-
- cached = result.toArray(new PsiMethod[result.size()]);
- if (stamp.mayCacheNow()) {
- myConstructors = cached;
- }
- }
- return cached;
+ return myCache.getConstructors();
}
@NotNull
public GrMethod[] getCodeConstructors() {
- GrMethod[] cached = myCodeConstructors;
- if (cached == null) {
- RecursionGuard.StackStamp stamp = ourGuard.markStack();
- List<GrMethod> result = new ArrayList<GrMethod>();
- for (final GrMethod method : getCodeMethods()) {
- if (method.isConstructor()) {
- result.add(method);
- }
- }
-
- cached = result.toArray(new GrMethod[result.size()]);
- if (stamp.mayCacheNow()) {
- myCodeConstructors = cached;
- }
- }
- return cached;
+ return myCache.getCodeConstructors();
}
@NotNull
public PsiClass[] getInnerClasses() {
- PsiClass[] inners = myInnerClasses;
- if (inners == null) {
- RecursionGuard.StackStamp stamp = ourGuard.markStack();
- final GrTypeDefinitionBody body = getBody();
- inners = body != null ? body.getInnerClasses() : PsiClass.EMPTY_ARRAY;
- if (stamp.mayCacheNow()) {
- myInnerClasses = inners;
- }
- }
-
- return inners;
+ return myCache.getInnerClasses();
}
@NotNull
public GrClassInitializer[] getInitializers() {
GrTypeDefinitionBody body = getBody();
- if (body == null) return GrClassInitializer.EMPTY_ARRAY;
-
- return body.getInitializers();
+ return body != null ? body.getInitializers() : GrClassInitializer.EMPTY_ARRAY;
}
@NotNull
@@ -680,7 +559,8 @@ public abstract class GrTypeDefinitionImpl extends GrStubElementBase<GrTypeDefin
}
@Nullable
- public Icon getIcon(int flags) {
+ @Override
+ protected Icon getElementIcon(@IconFlags int flags) {
Icon icon = getIconInner();
final boolean isLocked = (flags & ICON_FLAG_READ_STATUS) != 0 && !isWritable();
RowIcon rowIcon = createLayeredIcon(this, icon, ElementPresentationUtil.getFlags(this, isLocked) | getFlagsInner());
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionMembersCache.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionMembersCache.java
new file mode 100644
index 000000000000..3a2ec2cfe6ef
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionMembersCache.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.typedef;
+
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.Nullable;
+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.api.statements.typedef.GrTypeDefinitionBody;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+import org.jetbrains.plugins.groovy.lang.resolve.ast.AstTransformContributor;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static com.intellij.psi.util.PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT;
+import static org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil.addExpandingReflectedMethods;
+import static org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil.collectMethodsFromBody;
+
+/**
+ * Created by Max Medvedev on 03/03/14
+ */
+public class GrTypeDefinitionMembersCache {
+ private static final Condition<PsiMethod> CONSTRUCTOR_CONDITION = new Condition<PsiMethod>() {
+ @Override
+ public boolean value(PsiMethod method) {
+ return method.isConstructor();
+ }
+ };
+
+ private final MyModificationTracker myTreeChangeTracker = new MyModificationTracker();
+
+ private final GrTypeDefinition myDefinition;
+
+ public GrTypeDefinitionMembersCache(GrTypeDefinition definition) {
+ myDefinition = definition;
+ }
+
+
+ public GrMethod[] getCodeMethods() {
+ return CachedValuesManager.getCachedValue(myDefinition, new CachedValueProvider<GrMethod[]>() {
+ @Nullable
+ @Override
+ public Result<GrMethod[]> compute() {
+ GrTypeDefinitionBody body = myDefinition.getBody();
+ GrMethod[] methods = body != null ? body.getMethods() : GrMethod.EMPTY_ARRAY;
+ return Result.create(methods, myTreeChangeTracker);
+ }
+ });
+ }
+
+ public GrMethod[] getCodeConstructors() {
+ return CachedValuesManager.getCachedValue(myDefinition, new CachedValueProvider<GrMethod[]>() {
+ @Nullable
+ @Override
+ public Result<GrMethod[]> compute() {
+ GrTypeDefinitionBody body = myDefinition.getBody();
+ GrMethod[] methods;
+ if (body != null) {
+ List<GrMethod> result = ContainerUtil.findAll(body.getMethods(), CONSTRUCTOR_CONDITION);
+ methods = result.toArray(new GrMethod[result.size()]);
+ }
+ else {
+ methods = GrMethod.EMPTY_ARRAY;
+ }
+ return Result.create(methods, myTreeChangeTracker);
+ }
+ });
+ }
+
+ public PsiMethod[] getConstructors() {
+ return CachedValuesManager.getCachedValue(myDefinition, new CachedValueProvider<PsiMethod[]>() {
+ @Nullable
+ @Override
+ public Result<PsiMethod[]> compute() {
+ List<PsiMethod> result = ContainerUtil.findAll(myDefinition.getMethods(), CONSTRUCTOR_CONDITION);
+ return Result.create(result.toArray(new PsiMethod[result.size()]), myTreeChangeTracker, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
+ }
+ });
+ }
+
+
+ public PsiClass[] getInnerClasses() {
+ return CachedValuesManager.getCachedValue(myDefinition, new CachedValueProvider<PsiClass[]>() {
+ @Nullable
+ @Override
+ public Result<PsiClass[]> compute() {
+ final GrTypeDefinitionBody body = myDefinition.getBody();
+ PsiClass[] inners = body != null ? body.getInnerClasses() : PsiClass.EMPTY_ARRAY;
+ return Result.create(inners, myTreeChangeTracker);
+ }
+ });
+ }
+
+ public GrField[] getFields() {
+ return CachedValuesManager.getCachedValue(myDefinition, new CachedValueProvider<GrField[]>() {
+ @Nullable
+ @Override
+ public Result<GrField[]> compute() {
+ return Result.create(getFieldsImpl(), myTreeChangeTracker, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
+ }
+ });
+ }
+
+ private GrField[] getFieldsImpl() {
+ GrField[] codeFields = myDefinition.getCodeFields();
+
+ List<GrField> fromAstTransform = getSyntheticFields();
+ if (fromAstTransform.isEmpty()) return codeFields;
+
+ GrField[] res = new GrField[codeFields.length + fromAstTransform.size()];
+ System.arraycopy(codeFields, 0, res, 0, codeFields.length);
+
+ for (int i = 0; i < fromAstTransform.size(); i++) {
+ res[codeFields.length + i] = fromAstTransform.get(i);
+ }
+
+ return res;
+ }
+
+ private List<GrField> getSyntheticFields() {
+ return CachedValuesManager.getCachedValue(myDefinition, new CachedValueProvider<List<GrField>>() {
+ @Nullable
+ @Override
+ public Result<List<GrField>> compute() {
+ return Result.create(AstTransformContributor.runContributorsForFields(myDefinition), myTreeChangeTracker, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
+ }
+ });
+ }
+
+ public PsiMethod[] getMethods() {
+ return CachedValuesManager.getCachedValue(myDefinition, new CachedValueProvider<PsiMethod[]>() {
+ @Override
+ public Result<PsiMethod[]> compute() {
+ List<PsiMethod> result = new ArrayList<PsiMethod>();
+ collectMethodsFromBody(myDefinition, result);
+
+ for (PsiMethod method : AstTransformContributor.runContributorsForMethods(myDefinition)) {
+ addExpandingReflectedMethods(result, method);
+ }
+
+ for (GrField field : getSyntheticFields()) {
+ ContainerUtil.addIfNotNull(result, field.getSetter());
+ Collections.addAll(result, field.getGetters());
+ }
+ return Result.create(result.toArray(new PsiMethod[result.size()]), myTreeChangeTracker, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
+ }
+ });
+ }
+
+ public void dropCaches() {
+ myTreeChangeTracker.inc();
+ }
+
+ private static class MyModificationTracker implements ModificationTracker {
+ private long myCount = 0;
+
+ @Override
+ public long getModificationCount() {
+ return myCount;
+ }
+
+ public void inc() {
+ myCount++;
+ }
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
index b608f2994ddc..4fa96fe439f9 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
@@ -297,8 +297,9 @@ public abstract class GrMethodBaseImpl extends GrStubElementBase<GrMethodStub> i
return true;
}
+ @Nullable
@Override
- public Icon getIcon(int flags) {
+ protected Icon getElementIcon(@IconFlags int flags) {
RowIcon baseIcon = ElementPresentationUtil.createLayeredIcon(JetgroovyIcons.Groovy.Method, this, false);
return ElementPresentationUtil.addVisibilityIcon(this, flags, baseIcon);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightField.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightField.java
index 2ce56128a061..204f4ada7d0b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightField.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightField.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,6 +21,9 @@ import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiType;
import com.intellij.psi.impl.ResolveScopeManager;
import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -42,11 +45,6 @@ import java.util.Map;
*/
public class GrLightField extends GrLightVariable implements GrField {
- protected GrAccessorMethod mySetter;
- protected GrAccessorMethod[] myGetters;
-
- protected boolean mySetterInitialized = false;
-
private final PsiClass myContainingClass;
public GrLightField(@NotNull PsiClass containingClass,
@@ -96,24 +94,27 @@ public class GrLightField extends GrLightVariable implements GrField {
return PsiUtil.isProperty(this);
}
+ @Nullable
@Override
public GrAccessorMethod getSetter() {
- if (mySetterInitialized) return mySetter;
-
- mySetter = GrAccessorMethodImpl.createSetterMethod(this);
- mySetterInitialized = true;
-
- return mySetter;
+ return CachedValuesManager.getCachedValue(this, new CachedValueProvider<GrAccessorMethod>() {
+ @Nullable
+ @Override
+ public Result<GrAccessorMethod> compute() {
+ return Result.create(GrAccessorMethodImpl.createSetterMethod(GrLightField.this), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
+ }
+ });
}
-
@NotNull
@Override
public GrAccessorMethod[] getGetters() {
- if (myGetters == null) {
- myGetters = GrAccessorMethodImpl.createGetterMethods(this);
- }
-
- return myGetters;
+ return CachedValuesManager.getCachedValue(this, new CachedValueProvider<GrAccessorMethod[]>() {
+ @Nullable
+ @Override
+ public Result<GrAccessorMethod[]> compute() {
+ return Result.create(GrAccessorMethodImpl.createGetterMethods(GrLightField.this), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
+ }
+ });
}
@NotNull
@@ -123,13 +124,6 @@ public class GrLightField extends GrLightVariable implements GrField {
}
@Override
- public void clearCaches() {
- mySetterInitialized = false;
- mySetter = null;
- myGetters = null;
- }
-
- @Override
public void setInitializerGroovy(GrExpression initializer) {
throw new IncorrectOperationException("cannot set initializer to light field!");
}
@@ -178,7 +172,6 @@ public class GrLightField extends GrLightVariable implements GrField {
@Override
public PsiElement setName(@NotNull String name) throws IncorrectOperationException {
PsiElement res = super.setName(name);
- clearCaches();
return res;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrScriptField.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrScriptField.java
index 42f9a912cad7..86f5bdb0e6bf 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrScriptField.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrScriptField.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,6 +23,7 @@ import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
@@ -45,10 +46,6 @@ public class GrScriptField extends GrLightField {
private GrScriptField(@NotNull GrVariable original, @NotNull GroovyScriptClass scriptClass) {
super(scriptClass, original.getName(), original.getType(), original);
- mySetterInitialized = true;
- mySetter = null;
- myGetters = GrAccessorMethod.EMPTY_ARRAY;
-
final GrLightModifierList modifierList = getModifierList();
for (@PsiModifier.ModifierConstant String modifier : PsiModifier.MODIFIERS) {
if (original.hasModifierProperty(modifier)) {
@@ -65,6 +62,17 @@ public class GrScriptField extends GrLightField {
}
}
+ @Nullable
+ @Override
+ public GrAccessorMethod getSetter() {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public GrAccessorMethod[] getGetters() {
+ return GrAccessorMethod.EMPTY_ARRAY;
+ }
@NotNull
public static GrScriptField getScriptField(@NotNull final GrVariable original) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java
index 92a013c7d069..5108e852e11e 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.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.
@@ -158,7 +158,9 @@ public class GroovyScriptClass extends LightElement implements PsiClass, Synthet
@NotNull
public PsiClassType[] getExtendsListTypes() {
final PsiClassType superClassFromDSL = GroovyDslFileIndex.pocessScriptSuperClasses(myFile);
- return new PsiClassType[]{ superClassFromDSL != null ? superClassFromDSL : TypesUtil.createTypeByFQClassName(GroovyCommonClassNames.GROOVY_LANG_SCRIPT, this)};
+ PsiClassType superClass = superClassFromDSL != null ? superClassFromDSL
+ : TypesUtil.createTypeByFQClassName(GroovyCommonClassNames.GROOVY_LANG_SCRIPT, this);
+ return new PsiClassType[]{superClass};
}
@NotNull
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java
index aa7ca4cd1f68..12e6e2cb13a9 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java
@@ -91,10 +91,11 @@ public class GrCodeReferenceElementImpl extends GrReferenceElementImpl<GrCodeRef
@Override
protected GrCodeReferenceElement bindWithQualifiedRef(@NotNull String qName) {
- final GrTypeArgumentList list = getTypeArgumentList();
- final String typeArgs = (list != null) ? list.getText() : "";
- final String text = qName + typeArgs;
- final GrCodeReferenceElement qualifiedRef = GroovyPsiElementFactory.getInstance(getProject()).createTypeOrPackageReference(text);
+ final GrCodeReferenceElement qualifiedRef = GroovyPsiElementFactory.getInstance(getProject()).createTypeOrPackageReference(qName);
+ final PsiElement list = getTypeArgumentList();
+ if (list != null) {
+ qualifiedRef.getNode().addChild(list.copy().getNode());
+ }
getNode().getTreeParent().replaceChild(getNode(), qualifiedRef.getNode());
return qualifiedRef;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureAsAnonymousParameterEnhancer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureAsAnonymousParameterEnhancer.java
index 165b5f72bcc3..4607533ce644 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureAsAnonymousParameterEnhancer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureAsAnonymousParameterEnhancer.java
@@ -29,7 +29,7 @@ import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesPr
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import java.util.Iterator;
-import java.util.Set;
+import java.util.List;
/**
* @author Max Medvedev
@@ -39,14 +39,14 @@ public class ClosureAsAnonymousParameterEnhancer extends AbstractClosureParamete
@Override
protected PsiType getClosureParameterType(GrClosableBlock closure, int index) {
- Set<PsiType> expectedTypes;
+ List<PsiType> expectedTypes;
if (closure.getParent() instanceof GrSafeCastExpression) {
GrSafeCastExpression safeCastExpression = (GrSafeCastExpression)closure.getParent();
GrTypeElement typeElement = safeCastExpression.getCastTypeElement();
if (typeElement != null) {
PsiType castType = typeElement.getType();
- expectedTypes = ContainerUtil.newHashSet(GroovyExpectedTypesProvider.getDefaultExpectedTypes(safeCastExpression));
+ expectedTypes = ContainerUtil.newArrayList(GroovyExpectedTypesProvider.getDefaultExpectedTypes(safeCastExpression));
for (Iterator<PsiType> iterator = expectedTypes.iterator(); iterator.hasNext(); ) {
if (!TypesUtil.isAssignable(iterator.next(), castType, closure)) {
iterator.remove();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java
index 2e88f33faa8d..3bea053115a0 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java
@@ -16,11 +16,9 @@
package org.jetbrains.plugins.groovy.lang.psi.typeEnhancers;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.containers.hash.HashMap;
import com.intellij.util.containers.hash.HashSet;
@@ -37,7 +35,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGd
import org.jetbrains.plugins.groovy.lang.psi.impl.GrRangeType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
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.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
@@ -133,17 +130,10 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
return null;
}
- PsiType fromSam = inferParameterTypeFromSAM((GrMethodCall)parent, closure, index);
- if (fromSam != null) {
- return fromSam;
- }
-
String methodName = findMethodName((GrMethodCall)parent);
GrExpression expression = ((GrMethodCall)parent).getInvokedExpression();
if (!(expression instanceof GrReferenceExpression)) return null;
-// final PsiElement resolved = ((GrReferenceExpression)expression).resolve();
-// if (!(resolved instanceof GrGdkMethod)) return null;
GrExpression qualifier = ((GrReferenceExpression)expression).getQualifierExpression();
if (qualifier == null) return null;
@@ -265,42 +255,6 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
}
@Nullable
- private static PsiType inferParameterTypeFromSAM(@NotNull GrMethodCall methodCall, @NotNull GrClosableBlock closure, int index) {
- if (!ClosureToSamConverter.isSamConversionAllowed(methodCall)) return null;
-
- GroovyResolveResult resolveResult = methodCall.advancedResolve();
- PsiElement resolved = resolveResult.getElement();
-
- if (!(resolved instanceof PsiMethod)) return null;
-
-
-
- Map<GrExpression,Pair<PsiParameter,PsiType>> map = GrClosureSignatureUtil.mapArgumentsToParameters(resolveResult, methodCall, false, true,
- methodCall.getNamedArguments(),
- methodCall.getExpressionArguments(),
- methodCall.getClosureArguments());
- if (map == null) return null;
-
- Pair<PsiParameter, PsiType> samParameter = map.get(closure);
- assert samParameter != null;
-
- PsiType samTypeSubstituted = samParameter.getSecond();
- if (!(samTypeSubstituted instanceof PsiClassType)) return null;
-
- MethodSignature samSignature = ClosureToSamConverter.findSAMSignature(samTypeSubstituted);
- if (samSignature == null) return null;
-
- PsiType[] parameterTypes = samSignature.getParameterTypes();
-
- if (index >= parameterTypes.length) {
- return null;
- }
-
- return parameterTypes[index];
- }
-
-
- @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);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParamsEnhancer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParamsEnhancer.java
new file mode 100644
index 000000000000..d71763079839
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParamsEnhancer.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 org.jetbrains.plugins.groovy.lang.psi.typeEnhancers;
+
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.*;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
+import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtil;
+import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
+import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Created by Max Medvedev on 27/02/14
+ */
+public class ClosureParamsEnhancer extends AbstractClosureParameterEnhancer {
+
+ @Nullable
+ @Override
+ protected PsiType getClosureParameterType(GrClosableBlock closure, int index) {
+ if (!GroovyConfigUtils.getInstance().isVersionAtLeast(closure, GroovyConfigUtils.GROOVY2_3)) return null;
+
+ final GrParameter[] parameters = closure.getAllParameters();
+ if (containsParametersWithDeclaredType(parameters)) {
+ return null;
+ }
+
+ List<PsiType[]> fittingSignatures = findFittingSignatures(closure);
+
+ if (fittingSignatures.size() == 1) {
+ PsiType[] expectedSignature = fittingSignatures.get(0);
+ return expectedSignature[index];
+ }
+
+ return null;
+ }
+
+ @NotNull
+ public static List<PsiType[]> findFittingSignatures(GrClosableBlock closure) {
+
+ final GrParameter[] parameters = closure.getAllParameters();
+
+ GrCall call = findCall(closure);
+ if (call == null) return Collections.emptyList();
+
+ GroovyResolveResult resolveResult = call.advancedResolve();
+ PsiElement element = resolveResult.getElement();
+
+ if (!(element instanceof PsiMethod)) {
+ return Collections.emptyList();
+ }
+
+ while (element instanceof PsiMirrorElement) {
+ element = ((PsiMirrorElement)element).getPrototype();
+ }
+
+ List<Pair<PsiParameter,PsiType>> params = ResolveUtil.collectExpectedParamsByArg(closure,
+ new GroovyResolveResult[]{resolveResult},
+ call.getNamedArguments(),
+ call.getExpressionArguments(),
+ call.getClosureArguments(), closure);
+ if (params.isEmpty()) return Collections.emptyList();
+
+ Pair<PsiParameter, PsiType> pair = params.get(0);
+
+ PsiParameter param = pair.getFirst();
+ PsiModifierList modifierList = param.getModifierList();
+ if (modifierList == null) return Collections.emptyList();
+
+ PsiAnnotation anno = modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_STC_CLOSURE_PARAMS);
+ if (anno == null) return Collections.emptyList();
+
+ PsiClass closureSignatureHint = GrAnnotationUtil.inferClassAttribute(anno, "value");
+ if (closureSignatureHint == null) return Collections.emptyList();
+
+ String qnameOfClosureSignatureHint = closureSignatureHint.getQualifiedName();
+ if (qnameOfClosureSignatureHint == null) return Collections.emptyList();
+
+ SignatureHintProcessor signatureHintProcessor = SignatureHintProcessor.getHintProcessor(qnameOfClosureSignatureHint);
+ if (signatureHintProcessor == null) return Collections.emptyList();
+
+ List<PsiType[]> expectedSignatures = signatureHintProcessor.inferExpectedSignatures((PsiMethod)element,
+ resolveResult.getSubstitutor(),
+ SignatureHintProcessor.buildOptions(anno));
+
+ return ContainerUtil.findAll(expectedSignatures, new Condition<PsiType[]>() {
+ @Override
+ public boolean value(PsiType[] types) {
+ return types.length == parameters.length;
+ }
+ });
+ }
+
+ private static boolean containsParametersWithDeclaredType(GrParameter[] parameters) {
+ return ContainerUtil.find(parameters, new Condition<GrParameter>() {
+ @Override
+ public boolean value(GrParameter parameter) {
+ return parameter.getDeclaredType() != null;
+ }
+ }) != null;
+ }
+
+ @Nullable
+ private static GrCall findCall(@NotNull GrClosableBlock closure) {
+ PsiElement parent = closure.getParent();
+ if (parent instanceof GrCall && ArrayUtil.contains(closure, ((GrCall)parent).getClosureArguments())) {
+ return (GrCall)parent;
+ }
+
+ if (parent instanceof GrArgumentList) {
+ PsiElement pparent = parent.getParent();
+ if (pparent instanceof GrCall) {
+ return (GrCall)pparent;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/FirstParamHintProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/FirstParamHintProcessor.java
new file mode 100644
index 000000000000..7fdc10341c41
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/FirstParamHintProcessor.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.typeEnhancers;
+
+import com.intellij.psi.PsiArrayType;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiSubstitutor;
+import com.intellij.psi.PsiType;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Created by Max Medvedev on 28/02/14
+ */
+public class FirstParamHintProcessor extends ParamHintProcessor {
+ public FirstParamHintProcessor() {
+ super("groovy.transform.stc.FirstParam", 0, -1);
+ }
+
+ public static class FirstGeneric extends ParamHintProcessor {
+ public FirstGeneric() {
+ super("groovy.transform.stc.FirstParam.FirstGenericType", 0, 0);
+ }
+ }
+
+ public static class SecondGeneric extends ParamHintProcessor {
+ public SecondGeneric() {
+ super("groovy.transform.stc.FirstParam.SecondGenericType", 0, 1);
+ }
+ }
+
+ public static class ThirdGeneric extends ParamHintProcessor {
+ public ThirdGeneric() {
+ super("groovy.transform.stc.FirstParam.ThirdGenericType", 0, 2);
+ }
+ }
+
+ public static class Component extends SignatureHintProcessor {
+ @Override
+ public String getHintName() {
+ return "groovy.transform.stc.FirstParam.Component";
+ }
+
+ @NotNull
+ @Override
+ public List<PsiType[]> inferExpectedSignatures(@NotNull PsiMethod method,
+ @NotNull PsiSubstitutor substitutor,
+ @NotNull String[] options) {
+ List<PsiType[]> signatures = new FirstParamHintProcessor().inferExpectedSignatures(method, substitutor, options);
+ if (signatures.size() == 1) {
+ PsiType[] signature = signatures.get(0);
+ if (signature.length == 1) {
+ PsiType type = signature[0];
+ if (type instanceof PsiArrayType) {
+ return produceResult(((PsiArrayType)type).getComponentType());
+ }
+ }
+ }
+ return Collections.emptyList();
+ }
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/FromAbstractTypeMethodsHintProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/FromAbstractTypeMethodsHintProcessor.java
new file mode 100644
index 000000000000..d1c666fda47b
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/FromAbstractTypeMethodsHintProcessor.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.typeEnhancers;
+
+import com.intellij.codeInsight.generation.OverrideImplementExploreUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.util.MethodSignature;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Created by Max Medvedev on 28/02/14
+ */
+public class FromAbstractTypeMethodsHintProcessor extends SignatureHintProcessor {
+ @Override
+ public String getHintName() {
+ return "groovy.transform.stc.FromAbstractTypeMethods";
+ }
+
+ @NotNull
+ @Override
+ public List<PsiType[]> inferExpectedSignatures(@NotNull PsiMethod method,
+ @NotNull PsiSubstitutor substitutor,
+ @NotNull String[] options) {
+ if (options.length != 1) return Collections.emptyList();
+
+ String qname = options[0];
+ PsiClass aClass = JavaPsiFacade.getInstance(method.getProject()).findClass(qname, method.getResolveScope());
+ if (aClass == null) return Collections.emptyList();
+
+ Collection<MethodSignature> abstractSignatures = OverrideImplementExploreUtil.getMethodSignaturesToImplement(aClass);
+ return ContainerUtil.map(abstractSignatures, new Function<MethodSignature, PsiType[]>() {
+ @Override
+ public PsiType[] fun(MethodSignature signature) {
+ return signature.getParameterTypes();
+ }
+ });
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/FromStringHintProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/FromStringHintProcessor.java
new file mode 100644
index 000000000000..6ca36c5bb70f
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/FromStringHintProcessor.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 org.jetbrains.plugins.groovy.lang.psi.typeEnhancers;
+
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiSubstitutor;
+import com.intellij.psi.PsiType;
+import com.intellij.util.Function;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * Created by Max Medvedev on 28/02/14
+ */
+public class FromStringHintProcessor extends SignatureHintProcessor {
+
+ @Override
+ public String getHintName() {
+ return "groovy.transform.stc.FromString";
+ }
+
+ @NotNull
+ @Override
+ public List<PsiType[]> inferExpectedSignatures(@NotNull final PsiMethod method,
+ @NotNull final PsiSubstitutor substitutor,
+ @NotNull String[] options) {
+ return ContainerUtil.map(options, new Function<String, PsiType[]>() {
+ @Override
+ public PsiType[] fun(String value) {
+ String[] params = value.split(",");
+ return ContainerUtil.map(params, new Function<String, PsiType>() {
+ @Override
+ public PsiType fun(String param) {
+ try {
+ PsiType original = JavaPsiFacade.getElementFactory(method.getProject()).createTypeFromText(param, method);
+ return substitutor.substitute(original);
+ }
+ catch (IncorrectOperationException e) {
+ //do nothing. Just don't throw an exception
+ }
+ return PsiType.NULL;
+ }
+ }, new PsiType[params.length]);
+ }
+ });
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/MapEntryOrKeyValueHintProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/MapEntryOrKeyValueHintProcessor.java
new file mode 100644
index 000000000000..799d02a50dd0
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/MapEntryOrKeyValueHintProcessor.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.typeEnhancers;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtilRt;
+import com.intellij.psi.*;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * Created by Max Medvedev on 28/02/14
+ */
+public class MapEntryOrKeyValueHintProcessor extends SignatureHintProcessor {
+ @Override
+ public String getHintName() {
+ return "groovy.transform.stc.MapEntryOrKeyValue";
+ }
+
+ @NotNull
+ @Override
+ public List<PsiType[]> inferExpectedSignatures(@NotNull PsiMethod method,
+ @NotNull PsiSubstitutor substitutor,
+ @NotNull String[] options) {
+ int argNum = extractArgNum(options);
+ boolean index = extractIndex(options);
+
+ PsiParameter[] parameters = method.getParameterList().getParameters();
+
+ if (argNum >= parameters.length) return ContainerUtil.emptyList();
+
+ PsiParameter parameter = parameters[argNum];
+ PsiType type = parameter.getType();
+ PsiType substituted = substitutor.substitute(type);
+
+ if (!InheritanceUtil.isInheritor(substituted, CommonClassNames.JAVA_UTIL_MAP)) return ContainerUtil.emptyList();
+
+ PsiType key = PsiUtil.substituteTypeParameter(substituted, CommonClassNames.JAVA_UTIL_MAP, 0, true);
+ PsiType value = PsiUtil.substituteTypeParameter(substituted, CommonClassNames.JAVA_UTIL_MAP, 1, true);
+
+ PsiClass mapEntry = JavaPsiFacade.getInstance(method.getProject()).findClass(CommonClassNames.JAVA_UTIL_MAP_ENTRY, method.getResolveScope());
+ if (mapEntry == null) return ContainerUtil.emptyList();
+
+ PsiClassType mapEntryType = JavaPsiFacade.getElementFactory(method.getProject()).createType(mapEntry, key, value);
+
+ PsiType[] keyValueSignature = index ? new PsiType[]{key, value, PsiType.INT} : new PsiType[]{key, value};
+ PsiType[] mapEntrySignature = index ? new PsiType[]{mapEntryType, PsiType.INT} : new PsiType[]{mapEntryType};
+
+ return ContainerUtil.newArrayList(keyValueSignature, mapEntrySignature);
+ }
+
+ private static int extractArgNum(String[] options) {
+
+
+ for (String value : options) {
+ Integer parsedValue = parseArgNum(value);
+ if (parsedValue != null) {
+ return parsedValue;
+ }
+ }
+
+ if (options.length == 1) {
+ return StringUtilRt.parseInt(options[0], 0);
+ }
+
+ return 0;
+ }
+
+ private static boolean extractIndex(String[] options) {
+ for (String value : options) {
+ Boolean parsedValue = parseIndex(value);
+ if (parsedValue != null) {
+ return parsedValue;
+ }
+ }
+
+ if (options.length == 1) {
+ return StringUtilRt.parseBoolean(options[0], false);
+ }
+
+ return false;
+ }
+
+ private static Boolean parseIndex(String value) {
+ Pair<String, String> pair = parseValue(value);
+ if (pair == null) return null;
+
+ Boolean parsedValue = StringUtilRt.parseBoolean(pair.getSecond(), false);
+ if ("index".equals(pair.getFirst())) {
+ return parsedValue;
+ }
+
+ return null;
+ }
+
+ private static Integer parseArgNum(String value) {
+ Pair<String, String> pair = parseValue(value);
+ if (pair == null) return null;
+
+ Integer parsedValue = StringUtilRt.parseInt(pair.getSecond(), 0);
+ if ("argNum".equals(pair.getFirst())) {
+ return parsedValue;
+ }
+
+ return null;
+ }
+
+ @Nullable
+ private static Pair<String, String> parseValue(String value) {
+ String[] splitted = value.split("=");
+
+ if (splitted.length == 2) {
+ return Pair.create(splitted[0].trim(), splitted[1].trim());
+ }
+
+ return null;
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ParamHintProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ParamHintProcessor.java
new file mode 100644
index 000000000000..3c9ac95506b5
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ParamHintProcessor.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.typeEnhancers;
+
+import com.intellij.psi.*;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.ContainerUtilRt;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Max Medvedev on 28/02/14
+ */
+public abstract class ParamHintProcessor extends SignatureHintProcessor {
+ private final int myParam;
+ private final int myGeneric;
+ private final String myHint;
+
+ public ParamHintProcessor(String hint, int param, int generic) {
+ myHint = hint;
+ myParam = param;
+ myGeneric = generic;
+ }
+
+ @Override
+ public String getHintName() {
+ return myHint;
+ }
+
+ @NotNull
+ @Override
+ public List<PsiType[]> inferExpectedSignatures(@NotNull PsiMethod method,
+ @NotNull PsiSubstitutor substitutor,
+ @NotNull String[] options) {
+ PsiParameter[] parameters = method.getParameterList().getParameters();
+ if (myParam < parameters.length) {
+ PsiParameter parameter = parameters[myParam];
+ PsiType originalType = parameter.getType();
+
+ PsiType substituted = substitutor.substitute(originalType);
+
+ if (myGeneric == -1) {
+ return produceResult(substituted);
+ }
+ else {
+ if (substituted instanceof PsiClassType) {
+ PsiType[] typeParameters = ((PsiClassType)substituted).getParameters();
+ if (myGeneric < typeParameters.length) {
+ return produceResult(typeParameters[myGeneric]);
+ }
+ //if (substituted.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
+ // return produceResult(TypesUtil.createType(CommonClassNames.JAVA_LANG_CHARACTER, method));
+ //}
+ }
+ }
+ }
+ return ContainerUtilRt.emptyList();
+ }
+
+ @NotNull
+ protected static ArrayList<PsiType[]> produceResult(@Nullable PsiType type) {
+ PsiType notNull = type != null ? type : PsiType.NULL;
+ PsiType[] signature = {notNull};
+ ArrayList<PsiType[]> result = ContainerUtil.newArrayList();
+ result.add(signature);
+ return result;
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/SecondParamHintProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/SecondParamHintProcessor.java
new file mode 100644
index 000000000000..fbfa821327d2
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/SecondParamHintProcessor.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 org.jetbrains.plugins.groovy.lang.psi.typeEnhancers;
+
+import com.intellij.psi.PsiArrayType;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiSubstitutor;
+import com.intellij.psi.PsiType;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Created by Max Medvedev on 28/02/14
+ */
+public class SecondParamHintProcessor extends ParamHintProcessor {
+ public SecondParamHintProcessor() {
+ super("groovy.transform.stc.SecondParam", 1, -1);
+ }
+
+ public static class FirstGeneric extends ParamHintProcessor {
+ public FirstGeneric() {
+ super("groovy.transform.stc.SecondParam.FirstGenericType", 1, 0);
+ }
+ }
+
+ public static class SecondGeneric extends ParamHintProcessor {
+ public SecondGeneric() {
+ super("groovy.transform.stc.SecondParam.SecondGenericType", 1, 1);
+ }
+ }
+
+ public static class ThirdGeneric extends ParamHintProcessor {
+ public ThirdGeneric() {
+ super("groovy.transform.stc.SecondParam.ThirdGenericType", 1, 2);
+ }
+ }
+
+ public static class Component extends SignatureHintProcessor {
+ @Override
+ public String getHintName() {
+ return "groovy.transform.stc.SecondParam.Component";
+ }
+
+ @NotNull
+ @Override
+ public List<PsiType[]> inferExpectedSignatures(@NotNull PsiMethod method,
+ @NotNull PsiSubstitutor substitutor,
+ @NotNull String[] options) {
+ List<PsiType[]> signatures = new SecondParamHintProcessor().inferExpectedSignatures(method, substitutor, options);
+ if (signatures.size() == 1) {
+ PsiType[] signature = signatures.get(0);
+ if (signature.length == 1) {
+ PsiType type = signature[0];
+ if (type instanceof PsiArrayType) {
+ return produceResult(((PsiArrayType)type).getComponentType());
+ }
+ }
+ }
+ return Collections.emptyList();
+ }
+ }
+
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/SignatureHintProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/SignatureHintProcessor.java
new file mode 100644
index 000000000000..44c8f2ac5094
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/SignatureHintProcessor.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.typeEnhancers;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.*;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Max Medvedev on 28/02/14
+ */
+public abstract class SignatureHintProcessor {
+ private static final ExtensionPointName<SignatureHintProcessor> EP_NAME = ExtensionPointName.create("org.intellij.groovy.signatureHintProcessor");
+
+ static String[] buildOptions(PsiAnnotation anno) {
+ PsiAnnotationMemberValue options = anno.findAttributeValue("options");
+ if (options instanceof PsiLiteral) {
+ Object value = ((PsiLiteral)options).getValue();
+ if (value instanceof String) {
+ return new String[]{(String)value};
+ }
+ }
+ else if (options instanceof PsiArrayInitializerMemberValue) {
+ PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)options).getInitializers();
+ ArrayList<String> result = ContainerUtil.newArrayList();
+ for (PsiAnnotationMemberValue initializer : initializers) {
+ if (initializer instanceof PsiLiteral) {
+ Object value = ((PsiLiteral)initializer).getValue();
+ if (value instanceof String) {
+ result.add((String)value);
+ }
+ }
+ }
+
+ return ArrayUtil.toStringArray(result);
+ }
+
+ return ArrayUtil.EMPTY_STRING_ARRAY;
+ }
+
+ public abstract String getHintName();
+
+ @NotNull
+ public abstract List<PsiType[]> inferExpectedSignatures(@NotNull PsiMethod method,
+ @NotNull PsiSubstitutor substitutor,
+ @NotNull String[] options);
+
+ @Nullable
+ public static SignatureHintProcessor getHintProcessor(@NotNull String hint) {
+ for (SignatureHintProcessor processor : EP_NAME.getExtensions()) {
+ if (hint.equals(processor.getHintName())) {
+ return processor;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/SimpleTypeHintProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/SimpleTypeHintProcessor.java
new file mode 100644
index 000000000000..dc5fafe40715
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/SimpleTypeHintProcessor.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.plugins.groovy.lang.psi.typeEnhancers;
+
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiSubstitutor;
+import com.intellij.psi.PsiType;
+import com.intellij.util.Function;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
+import org.codehaus.groovy.runtime.DefaultGroovyMethods;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Created by Max Medvedev on 28/02/14
+ */
+public class SimpleTypeHintProcessor extends SignatureHintProcessor {
+ @Override
+ public String getHintName() {
+ return "groovy.transform.stc.SimpleType";
+ }
+
+ @NotNull
+ @Override
+ public List<PsiType[]> inferExpectedSignatures(@NotNull final PsiMethod method,
+ @NotNull PsiSubstitutor substitutor,
+ @NotNull String[] options) {
+ return Collections.singletonList(ContainerUtil.map(options, new Function<String, PsiType>() {
+ @Override
+ public PsiType fun(String value) {
+ try {
+ PsiType type = JavaPsiFacade.getElementFactory(method.getProject()).createTypeFromText(value, method);
+ return DefaultGroovyMethods.asBoolean(type) ? type : PsiType.NULL;
+ }
+ catch (IncorrectOperationException e) {
+ return PsiType.NULL;
+ }
+ }
+ }, new PsiType[options.length]));
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ThirdParamHintProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ThirdParamHintProcessor.java
new file mode 100644
index 000000000000..89d935593b1a
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ThirdParamHintProcessor.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 org.jetbrains.plugins.groovy.lang.psi.typeEnhancers;
+
+import com.intellij.psi.PsiArrayType;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiSubstitutor;
+import com.intellij.psi.PsiType;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Created by Max Medvedev on 28/02/14
+ */
+public class ThirdParamHintProcessor extends ParamHintProcessor {
+ public ThirdParamHintProcessor() {
+ super("groovy.transform.stc.ThirdParam", 2, -1);
+ }
+
+ public static class FirstGeneric extends ParamHintProcessor {
+ public FirstGeneric() {
+ super("groovy.transform.stc.ThirdParam.FirstGenericType", 2, 0);
+ }
+ }
+
+ public static class SecondGeneric extends ParamHintProcessor {
+ public SecondGeneric() {
+ super("groovy.transform.stc.ThirdParam.SecondGenericType", 2, 1);
+ }
+ }
+
+ public static class ThirdGeneric extends ParamHintProcessor {
+ public ThirdGeneric() {
+ super("groovy.transform.stc.ThirdParam.ThirdGenericType", 2, 2);
+ }
+ }
+
+ public static class Component extends SignatureHintProcessor {
+ @Override
+ public String getHintName() {
+ return "groovy.transform.stc.ThirdParam.Component";
+ }
+
+ @NotNull
+ @Override
+ public List<PsiType[]> inferExpectedSignatures(@NotNull PsiMethod method,
+ @NotNull PsiSubstitutor substitutor,
+ @NotNull String[] options) {
+ List<PsiType[]> signatures = new ThirdParamHintProcessor().inferExpectedSignatures(method, substitutor, options);
+ if (signatures.size() == 1) {
+ PsiType[] signature = signatures.get(0);
+ if (signature.length == 1) {
+ PsiType type = signature[0];
+ if (type instanceof PsiArrayType) {
+ return produceResult(((PsiArrayType)type).getComponentType());
+ }
+ }
+ }
+ return Collections.emptyList();
+ }
+ }
+
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.java
index dc08b531786e..75496889f9a4 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.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.
@@ -617,7 +617,7 @@ public class GrClassImplUtil {
private static boolean shouldImplementDelegatedInterfaces(PsiAnnotation delegate) {
final Boolean result = GrAnnotationUtil.inferBooleanAttribute(delegate, "interfaces");
- return result != null ? result.booleanValue() : true;
+ return result == null || result.booleanValue();
}
public static void addExpandingReflectedMethods(List<PsiMethod> result, PsiMethod method) {
@@ -631,12 +631,12 @@ public class GrClassImplUtil {
result.add(method);
}
- public static void collectMethodsFromBody(@NotNull GrTypeDefinitionBody body, List<PsiMethod> result) {
- for (GrMethod method : body.getMethods()) {
+ public static void collectMethodsFromBody(@NotNull GrTypeDefinition definition, List<PsiMethod> result) {
+ for (GrMethod method : definition.getCodeMethods()) {
addExpandingReflectedMethods(result, method);
}
- for (GrField field : body.getFields()) {
+ for (GrField field : definition.getFields()) {
if (!field.isProperty()) continue;
ContainerUtil.addAll(result, field.getGetters());
ContainerUtil.addIfNotNull(result, field.getSetter());
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java
index cfd5a265f6c8..0cf18709c585 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.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.
@@ -68,7 +68,7 @@ public final class GroovyCommonClassNames {
@NonNls public static final String GROOVY_LANG_DELEGATES_TO = "groovy.lang.DelegatesTo";
@NonNls public static final String GROOVY_LANG_DELEGATES_TO_TARGET = "groovy.lang.DelegatesTo.Target";
@NonNls public static final String GROOVY_TRANSFORM_COMPILE_DYNAMIC = "groovy.transform.CompileDynamic";
-
+ @NonNls public static final String GROOVY_TRANSFORM_STC_CLOSURE_PARAMS = "groovy.transform.stc.ClosureParams";
public static final Set<String> GROOVY_EXTENSION_CLASSES = Collections.unmodifiableSet(ContainerUtil.newLinkedHashSet(
"org.codehaus.groovy.runtime.DateGroovyMethods",
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java
index 98bd1d918f5c..ad16d8d71297 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java
@@ -48,6 +48,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
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.blocks.GrClosableBlock;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
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;
@@ -916,6 +917,33 @@ public class ResolveUtil {
}
}
+ @NotNull
+ public static List<Pair<PsiParameter, PsiType>> collectExpectedParamsByArg(@NotNull PsiElement place,
+ @NotNull GroovyResolveResult[] variants,
+ @NotNull GrNamedArgument[] namedArguments,
+ @NotNull GrExpression[] expressionArguments,
+ @NotNull GrClosableBlock[] closureArguments,
+ @NotNull GrExpression arg) {
+ List<Pair<PsiParameter, PsiType>> expectedParams = ContainerUtil.newArrayList();
+
+ for (GroovyResolveResult variant : variants) {
+ final Map<GrExpression, Pair<PsiParameter, PsiType>> map = GrClosureSignatureUtil.mapArgumentsToParameters(
+ variant, place, true, true, namedArguments, expressionArguments, closureArguments
+ );
+
+ if (map != null) {
+ final Pair<PsiParameter, PsiType> pair = map.get(arg);
+ ContainerUtil.addIfNotNull(expectedParams, pair);
+ }
+ }
+ return expectedParams;
+ }
+
+ @NotNull
+ public static List<Pair<PsiParameter, PsiType>> collectExpectedParamsByArg(@NotNull GrCall call, @NotNull GrExpression arg) {
+ return collectExpectedParamsByArg(arg, call.getCallVariants(arg), call.getNamedArguments(), call.getExpressionArguments(), call.getClosureArguments(), arg);
+ }
+
private static class DuplicateVariablesProcessor extends PropertyResolverProcessor {
private boolean myBorderPassed;
private final boolean myHasVisibilityModifier;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java
index 2aa286e972bc..edb458e2d94c 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ast/DelegatedMethodsContributor.java
@@ -37,7 +37,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrExtendsClause;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrImplementsClause;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
@@ -117,10 +116,7 @@ public class DelegatedMethodsContributor extends AstTransformContributor {
final List<PsiMethod> methods;
if (clazz instanceof GrTypeDefinition) {
methods = new ArrayList<PsiMethod>();
- final GrTypeDefinitionBody body = ((GrTypeDefinition)clazz).getBody();
- if (body != null) {
- GrClassImplUtil.collectMethodsFromBody(body, methods);
- }
+ GrClassImplUtil.collectMethodsFromBody((GrTypeDefinition)clazz, methods);
}
else {
methods = Arrays.asList(clazz.getMethods());
@@ -247,10 +243,7 @@ public class DelegatedMethodsContributor extends AstTransformContributor {
final List<PsiMethod> methods;
if (currentClass instanceof GrTypeDefinition) {
methods = new ArrayList<PsiMethod>();
- final GrTypeDefinitionBody body = ((GrTypeDefinition)currentClass).getBody();
- if (body != null) {
- GrClassImplUtil.collectMethodsFromBody(body, methods);
- }
+ GrClassImplUtil.collectMethodsFromBody((GrTypeDefinition)currentClass, methods);
}
else {
methods = Arrays.asList(currentClass.getMethods());
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java
index 10e93acc5a22..e78cc0800d24 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java
@@ -730,7 +730,7 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
return candidate;
}
- public static void assertStatement(@NotNull PsiElement anchor, @NotNull PsiElement scope) {
+ public static void assertStatement(@Nullable PsiElement anchor, @NotNull PsiElement scope) {
if (!(anchor instanceof GrStatement)) {
LogMessageEx.error(LOG, "cannot find anchor for variable", scope.getText());
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java
index 9f1a9848476f..165f0f58e669 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java
@@ -188,7 +188,10 @@ public class GrIntroduceParameterHandler implements RefactoringActionHandler, Me
private static boolean isInplace(@NotNull IntroduceParameterInfo info,
@NotNull Editor editor) {
- return findExpr(info) != null && GrIntroduceHandlerBase.isInplace(editor, info.getContext());
+ return findExpr(info) != null &&
+ info.getToReplaceIn() instanceof GrMethod &&
+ info.getToSearchFor() instanceof PsiMethod &&
+ GrIntroduceHandlerBase.isInplace(editor, info.getContext());
}
@Override
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/dynamicMembers/GrDynamicPropertyImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/dynamicMembers/GrDynamicPropertyImpl.java
index 1521684d1d9c..ecd79e61acc4 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/dynamicMembers/GrDynamicPropertyImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/dynamicMembers/GrDynamicPropertyImpl.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.
@@ -202,11 +202,6 @@ public class GrDynamicPropertyImpl extends LightElement implements GrField {
}
@Override
- public void clearCaches() {
- myField.clearCaches();
- }
-
- @Override
public void setInitializerGroovy(GrExpression initializer) {
throw new IncorrectOperationException("cannot set initializer to dynamic property!");
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/FastGroovyTestSuite.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/FastGroovyTestSuite.java
index 11597e915fe4..42404baeec57 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/FastGroovyTestSuite.java
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/FastGroovyTestSuite.java
@@ -19,7 +19,6 @@ import com.intellij.TestAll;
import com.intellij.TestCaseLoader;
import junit.framework.Test;
import junit.framework.TestSuite;
-import org.jetbrains.plugins.groovy.compiler.GppCompilerTest;
import org.jetbrains.plugins.groovy.compiler.GroovyCompilerTest;
import org.jetbrains.plugins.groovy.compiler.GroovyDebuggerTest;
import org.jetbrains.plugins.groovy.lang.GroovyStressPerformanceTest;
@@ -46,8 +45,7 @@ public class FastGroovyTestSuite {
private static boolean isSlow(Class aClass) {
return aClass.equals(GroovyDebuggerTest.class) ||
aClass.equals(GroovyStressPerformanceTest.class) ||
- aClass.getName().startsWith(GroovyCompilerTest.class.getName()) ||
- aClass.getName().startsWith(GppCompilerTest.class.getName());
+ aClass.getName().startsWith(GroovyCompilerTest.class.getName());
}
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy
deleted file mode 100644
index 316de960091c..000000000000
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy
+++ /dev/null
@@ -1,136 +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 org.jetbrains.plugins.groovy.compiler
-
-import com.intellij.compiler.CompilerConfiguration
-import com.intellij.compiler.CompilerConfigurationImpl
-import com.intellij.compiler.server.BuildManager
-import com.intellij.openapi.util.io.FileUtil
-import com.intellij.openapi.vfs.VfsUtil
-import com.intellij.testFramework.PsiTestUtil
-import org.jetbrains.plugins.groovy.util.TestUtils
-/**
- * @author peter
- */
-public abstract class GppCompilerTest extends GroovyCompilerTestCase {
- String[] oldPatterns
-
- @Override protected void setUp() {
- super.setUp();
- PsiTestUtil.addLibrary myFixture.module, "gpp", TestUtils.absoluteTestDataPath + "/realGroovypp/", "groovy-all-1.8.2.jar", "groovypp-all-0.9.0_1.8.2.jar"
- CompilerConfigurationImpl conf = CompilerConfiguration.getInstance(project)
- oldPatterns = conf.resourceFilePatterns
- conf.addResourceFilePattern("!*.gpp")
- }
-
- @Override
- protected void tearDown() {
- CompilerConfigurationImpl conf = CompilerConfiguration.getInstance(project)
- conf.removeResourceFilePatterns()
- oldPatterns.each { conf.addResourceFilePattern(it) }
- super.tearDown()
- }
-
- public void testRecompileDependentGroovyClasses() throws Exception {
- def a = myFixture.addFileToProject("A.gpp", """
-class A {
- void foo() {
- print "239"
- }
-}
-""")
- myFixture.addFileToProject("b.gpp", """
-new A().foo()
-""")
- assertEmpty make()
- assertOutput "b", "239"
-
- VfsUtil.saveText a.virtualFile, """
-class A {
- def foo() {
- print "239"
- }
-}
-"""
-
- assertEmpty make()
- assertOutput "b", "239"
- }
-
- public void testRecompileDependentJavaClasses() throws Exception {
- def a = myFixture.addFileToProject("A.gpp", """
-class A {
- void foo() {
- print "239"
- }
-}
-""")
- myFixture.addFileToProject("B.java", """
-public class B {
- public static void main(String[] args) {
- new A().foo();
- }
-}
-""")
- assertEmpty make()
- assertOutput "B", "239"
-
- VfsUtil.saveText a.virtualFile, """
-class A {
- def foo() {
- print "239"
- }
-}
-"""
-
- assertEmpty make()
- assertOutput "B", "239"
- }
-
- public static class IdeaModeTest extends GppCompilerTest {
- @Override
- protected boolean useJps() { false }
- }
-
- public static class JpsModeTest extends GppCompilerTest {
- @Override
- protected boolean useJps() { true }
-
- @Override
- void testRecompileDependentJavaClasses() {
- super.testRecompileDependentJavaClasses()
- }
-
- @Override
- void testRecompileDependentGroovyClasses() {
- super.testRecompileDependentGroovyClasses()
- }
-
- @Override
- protected void tearDown() {
- File systemRoot = BuildManager.getInstance().getBuildSystemDirectory()
- try {
- super.tearDown()
- }
- finally {
- FileUtil.delete(systemRoot);
- }
- }
- }
-
-
-}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy
index da3963e9b7e1..9be76d2096db 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy
@@ -17,9 +17,9 @@
package org.jetbrains.plugins.groovy.compiler
import com.intellij.compiler.CompilerConfiguration
import com.intellij.compiler.CompilerConfigurationImpl
+import com.intellij.compiler.impl.TranslatingCompilerFilesMonitor
import com.intellij.compiler.server.BuildManager
import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.application.PathManager
import com.intellij.openapi.compiler.CompilerMessage
import com.intellij.openapi.compiler.CompilerMessageCategory
import com.intellij.openapi.compiler.options.ExcludeEntryDescription
@@ -41,6 +41,12 @@ public abstract class GroovyCompilerTest extends GroovyCompilerTestCase {
addGroovyLibrary(myModule);
}
+ @Override
+ protected void tearDown() throws Exception {
+ TranslatingCompilerFilesMonitor.ourDebugMode = false
+ super.tearDown()
+ }
+
public void testPlainGroovy() throws Throwable {
myFixture.addFileToProject("A.groovy", "println '239'");
assertEmpty(make());
@@ -128,6 +134,8 @@ public abstract class GroovyCompilerTest extends GroovyCompilerTestCase {
}
public void testTransitiveJavaDependencyThroughGroovy() throws Throwable {
+ TranslatingCompilerFilesMonitor.ourDebugMode = true
+
myFixture.addClass("public class IFoo { void foo() {} }").getContainingFile().getVirtualFile();
myFixture.addFileToProject("Foo.groovy", "class Foo {\n" +
" static IFoo f\n" +
@@ -208,7 +216,7 @@ public abstract class GroovyCompilerTest extends GroovyCompilerTestCase {
@Override
void runBare() {
- new File(PathManager.systemPath, "compile-server/server.log").delete()
+ new File(TestLoggerFactory.testLogDir, "../log/build-log/build.log").delete()
super.runBare()
}
@@ -231,7 +239,7 @@ public abstract class GroovyCompilerTest extends GroovyCompilerTestCase {
def logText = ideaLog.text
println(logText.size() < limit ? logText : logText.substring(logText.size() - limit))
}
- def makeLog = new File(PathManager.systemPath, "compile-server/server.log")
+ def makeLog = new File(TestLoggerFactory.testLogDir, "../log/build-log/build.log")
if (makeLog.exists()) {
println "\n\nServer Log:"
println makeLog.text
@@ -725,11 +733,11 @@ public class Main {
ApplicationManager.application.runWriteAction { msg.virtualFile.delete(this) }
def messages = make()
- assert messages
+ assert messages
def error = messages.find { it.message.contains('InvalidType') }
assert error?.virtualFile
assert groovyFile.classes[0] == GroovycStubGenerator.findClassByStub(project, error.virtualFile)
-
+
}
public void "test ignore groovy internal non-existent interface helper inner class"() {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Gr2_3HighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Gr2_3HighlightingTest.groovy
new file mode 100644
index 000000000000..273eb8feca63
--- /dev/null
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Gr2_3HighlightingTest.groovy
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.highlighting
+
+import com.intellij.codeInspection.InspectionProfileEntry
+import com.intellij.testFramework.LightProjectDescriptor
+import org.jetbrains.plugins.groovy.GroovyLightProjectDescriptor
+import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection
+import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection
+
+/**
+ * Created by Max Medvedev on 27/02/14
+ */
+class Gr2_3HighlightingTest extends GrHighlightingTestBase {
+ @Override
+ protected LightProjectDescriptor getProjectDescriptor() {
+ return GroovyLightProjectDescriptor.GROOVY_2_3
+ }
+
+ @Override
+ InspectionProfileEntry[] getCustomInspections() {
+ [new GroovyAssignabilityCheckInspection(), new GrUnresolvedAccessInspection()]
+ }
+
+ void assertScript(String text) {
+ testHighlighting("import groovy.transform.CompileStatic\nimport groovy.transform.stc.ClosureParams\n" + text)
+ }
+
+ void shouldFailWithMessages(String text) {
+ assertScript(text)
+ }
+
+ void testInferenceOnNonExtensionMethod() {
+ assertScript '''
+import groovy.transform.stc.FirstParam
+
+public <T> T foo(T arg, @ClosureParams(FirstParam) Closure c) { c.call(arg) }
+
+@CompileStatic
+def test() {
+ assert foo('a') { it.toUpperCase() } == 'A'
+}
+'''
+ }
+
+ void testFromStringWithSimpleType() {
+ assertScript '''
+import groovy.transform.stc.FromString
+
+void foo(@ClosureParams(value=FromString,options="java.lang.String") Closure cl) { cl.call('foo') }
+
+@CompileStatic
+def test() {
+ foo { String str -> println str.toUpperCase()}
+}
+'''
+
+ shouldFailWithMessages '''
+import groovy.transform.stc.FromString
+
+void foo(@ClosureParams(value=FromString,options="java.lang.String") Closure cl) { cl.call('foo') }
+
+@CompileStatic
+def test() {
+ foo { <error descr="Expected String">Date</error> str -> println str}
+}
+'''
+ }
+
+ void testFromStringWithGenericType() {
+ assertScript '''
+import groovy.transform.stc.FromString
+
+void foo(@ClosureParams(value=FromString,options="java.util.List<java.lang.String>") Closure cl) { cl.call(['foo']) }
+
+@CompileStatic
+def test() {
+ foo { List<String> str -> str.each { println it.toUpperCase() } }
+}
+'''
+
+ shouldFailWithMessages '''
+import groovy.transform.stc.FromString
+
+void foo(@ClosureParams(value=FromString,options="java.util.List<java.lang.String>") Closure cl) { cl.call(['foo']) }
+
+@CompileStatic
+def test() {
+ foo { <error descr="Expected List<String>">List<Date></error> d -> d.each { println it } }
+}
+'''
+ }
+
+ void testFromStringWithDirectGenericPlaceholder() {
+
+ assertScript '''
+import groovy.transform.stc.FromString
+
+public <T> void foo(T t, @ClosureParams(value=FromString,options="T") Closure cl) { cl.call(t) }
+
+@CompileStatic
+def test() {
+ foo('hey') { println it.toUpperCase() }
+}
+'''
+
+ }
+
+ void testFromStringWithGenericPlaceholder() {
+ assertScript '''
+import groovy.transform.stc.FromString
+
+public <T> void foo(T t, @ClosureParams(value=FromString,options="java.util.List<T>") Closure cl) { cl.call([t,t]) }
+
+@CompileStatic
+def test() {
+ foo('hey') { List<String> str -> str.each { println it.toUpperCase() } }
+}
+'''
+
+ }
+
+ void testFromStringWithGenericPlaceholderFromClass() {
+ assertScript '''
+import groovy.transform.stc.FromString
+
+class Foo<T> {
+ public void foo(@ClosureParams(value=FromString,options="java.util.List<T>") Closure cl) { cl.call(['hey','ya']) }
+}
+
+@CompileStatic
+def test() {
+ def foo = new Foo<String>()
+
+ foo.foo { List<String> str -> str.each { println it.toUpperCase() } }
+}'''
+ }
+
+ void testFromStringWithGenericPlaceholderFromClassWithTwoGenerics() {
+ assertScript '''
+import groovy.transform.stc.FromString
+
+class Foo<T,U> {
+ public void foo(@ClosureParams(value=FromString,options="java.util.List<U>") Closure cl) { cl.call(['hey','ya']) }
+}
+
+@CompileStatic
+def test() {
+ def foo = new Foo<Integer,String>()
+
+ foo.foo { List<String> str -> str.each { println it.toUpperCase() } }
+}'''
+ }
+
+ void testFromStringWithGenericPlaceholderFromClassWithTwoGenericsAndNoExplicitSignature() {
+ assertScript '''
+import groovy.transform.stc.FromString
+
+class Foo<T,U> {
+ public void foo(@ClosureParams(value=FromString,options="java.util.List<U>") Closure cl) { cl.call(['hey','ya']) }
+}
+
+@CompileStatic
+def test() {
+ def foo = new Foo<Integer,String>()
+
+ foo.foo { it.each { println it.toUpperCase() } }
+}'''
+ }
+
+ void testFromStringWithGenericPlaceholderFromClassWithTwoGenericsAndNoExplicitSignatureAndNoFQN() {
+ assertScript '''
+import groovy.transform.stc.FromString
+
+class Foo<T,U> {
+ public void foo(@ClosureParams(value=FromString,options="List<U>") Closure cl) { cl.call(['hey','ya']) }
+}
+
+@CompileStatic
+def test() {
+ def foo = new Foo<Integer,String>()
+
+ foo.foo { it.each { println it.toUpperCase() } }
+}'''
+ }
+
+ void testFromStringWithGenericPlaceholderFromClassWithTwoGenericsAndNoExplicitSignatureAndNoFQNAndReferenceToSameUnitClass() {
+ assertScript '''
+import groovy.transform.stc.FromString
+
+class Foo {
+ void bar() {
+ println 'Haha!'
+ }
+}
+
+class Tor<D,U> {
+ public void foo(@ClosureParams(value=FromString,options="List<U>") Closure cl) { cl.call([new Foo(), new Foo()]) }
+}
+
+@CompileStatic
+def test() {
+ def tor = new Tor<Integer,Foo>()
+
+ tor.foo { it.each { it.bar() } }
+}'''
+ }
+
+ void testFromStringWithGenericPlaceholderFromClassWithTwoGenericsAndNoExplicitSignatureAndNoFQNAndReferenceToSameUnitClassAndTwoArgs() {
+ assertScript '''
+import groovy.transform.stc.FromString
+
+class Foo {
+ void bar() {
+ println 'Haha!'
+ }
+}
+
+class Tor<D,U> {
+ public void foo(@ClosureParams(value=FromString,options=["D,List<U>"]) Closure cl) { cl.call(3, [new Foo(), new Foo()]) }
+}
+
+@CompileStatic
+def test() {
+
+ def tor = new Tor<Integer,Foo>()
+
+ tor.foo { r, e -> r.times { e.each { it.bar() } } }
+}
+'''
+ }
+
+ void testFromStringWithGenericPlaceholderFromClassWithTwoGenericsAndPolymorphicSignature() {
+ assertScript '''
+import groovy.transform.stc.FromString
+
+class Foo {
+ void bar() {
+ println 'Haha!'
+ }
+}
+
+class Tor<D,U> {
+ public void foo(@ClosureParams(value=FromString,options=["D,List<U>", "D"]) Closure cl) {
+ if (cl.maximumNumberOfParameters==2) {
+ cl.call(3, [new Foo(), new Foo()])
+ } else {
+ cl.call(3)
+ }
+ }
+}
+
+@CompileStatic
+def test() {
+ def tor = new Tor<Integer,Foo>()
+
+ tor.foo { r, e -> r.times { e.each { it.bar() } } }
+ tor.foo { it.times { println 'polymorphic' } }
+}
+'''
+ }
+}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrInspectionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrInspectionTest.groovy
index 2b9ecad11444..246c5ca0b7f5 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrInspectionTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrInspectionTest.groovy
@@ -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.
@@ -26,9 +26,9 @@ import org.jetbrains.plugins.groovy.codeInspection.declaration.GrMethodMayBeStat
import org.jetbrains.plugins.groovy.codeInspection.exception.GroovyEmptyCatchBlockInspection
import org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyOverlyLongMethodInspection
import org.jetbrains.plugins.groovy.codeInspection.noReturnMethod.MissingReturnInspection
-import org.jetbrains.plugins.groovy.codeInspection.threading.GroovyUnconditionalWaitInspection
import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection
import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUntypedAccessInspection
+
/**
* @author Max Medvedev
*/
@@ -146,29 +146,6 @@ boolean bar(def list) {
''', MissingReturnInspection)
}
- void testReassignedVarInClosureInspection() {
- addCompileStatic()
- testHighlighting("""\
-test() {
- def var = "abc"
- def cl = {
- <warning descr="Local variable 'var' is reassigned">var</warning> = new Date()
- }
- cl()
- var.toUpperCase()
-}
-
-test2() {
- def var = "abc"
- def cl = {
- <warning descr="Local variable 'var' is reassigned">var</warning> = 'cde'
- }
- cl()
- var.toUpperCase()
-}
-""", GrReassignedInClosureLocalVarInspection)
- }
-
void testPackageDefinition() {
myFixture.addFileToProject('cde/bar.groovy', '//empty file')
myFixture.addFileToProject('abc/foo.groovy', '''\
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/optimizeImports/GroovyAddImportActionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/optimizeImports/GroovyAddImportActionTest.groovy
index 54543f271545..97fb5d1345dc 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/optimizeImports/GroovyAddImportActionTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/optimizeImports/GroovyAddImportActionTest.groovy
@@ -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,7 @@
*/
package org.jetbrains.plugins.groovy.refactoring.optimizeImports
-
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
-import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection
/**
* @author peter
*/
@@ -27,20 +25,34 @@ public class GroovyAddImportActionTest extends LightCodeInsightFixtureTestCase {
myFixture.addClass 'package foo; public class Log {}'
myFixture.addClass 'package bar; public class Log {}'
myFixture.addClass 'package bar; public class LogFactory { public static Log log(){} }'
- myFixture.configureByText 'a.groovy', '''
+ doTest('''\
public class Foo {
Lo<caret>g l = bar.LogFactory.log();
}
-'''
- myFixture.enableInspections(new GrUnresolvedAccessInspection())
-
- importClass()
- myFixture.checkResult '''import bar.Log
+''', '''\
+import bar.Log
public class Foo {
Lo<caret>g l = bar.LogFactory.log();
}
-'''
+''')
+ }
+
+ void testReferenceWithErrors() {
+ myFixture.addClass 'package foo; public class Abc<X, Y> {}'
+ doTest('''\
+A<caret>bc<String, > foo = null
+''', '''\
+import foo.Abc
+
+A<caret>bc<String, > foo = null
+''')
+ }
+
+ private void doTest(String before, String after) {
+ myFixture.configureByText 'a.groovy', before
+ importClass()
+ myFixture.checkResult after
}
private def importClass() {
diff --git a/plugins/groovy/testdata/mockGroovyLib2.3/groovy-all-2.3.0.jar b/plugins/groovy/testdata/mockGroovyLib2.3/groovy-all-2.3.0.jar
index 3b5173f970df..720d4a962bac 100644
--- a/plugins/groovy/testdata/mockGroovyLib2.3/groovy-all-2.3.0.jar
+++ b/plugins/groovy/testdata/mockGroovyLib2.3/groovy-all-2.3.0.jar
Binary files differ
diff --git a/plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties b/plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties
index 1531965a2445..5f5a1679709f 100644
--- a/plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties
+++ b/plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties
@@ -132,3 +132,4 @@ hg4idea.changelist.column.branch=Branch
hg4idea.annotation.tool.tip=commit {0}\nAuthor: {1}\nDate: {2}\n\n{3}
hg4idea.push.asNewBranch=push as &new remote branch
+hg4idea.push.bookmark=Book&mark
diff --git a/plugins/hg4idea/src/META-INF/plugin.xml b/plugins/hg4idea/src/META-INF/plugin.xml
index ba40408dd98d..f0ce13c23b43 100644
--- a/plugins/hg4idea/src/META-INF/plugin.xml
+++ b/plugins/hg4idea/src/META-INF/plugin.xml
@@ -1,7 +1,17 @@
<idea-plugin>
<id>hg4idea</id>
<name>hg4idea</name>
- <description>Provides integration with Mercurial version control system. Supports Mercurial 1.3+.</description>
+ <description>
+ <![CDATA[
+ Allows working with <a href="http://mercurial.selenic.com/">Mercurial version control system</a>.
+ The following features are available:
+ <ul>
+ <li>Dedicated page under the Version Control node in the Settings/Preferences dialog.</li>
+ <li>Ability to browse, check out sources from and import into the available Mercurial repositories, when Mercurial is not enabled.</li>
+ <li>When Mercurial is enabled, the Mercurial node appears on the VCS menu, and on the context menu of the editor.
+ </ul>
+ ]]>
+ </description>
<category>VCS Integration</category>
<version>10.0</version>
<vendor email="victor.iacoban@gmail.com, willem.verstraeten@gmail.com" url="http://www.bitbucket.org/willemv/hg4idea">Victor Iacoban and Willem Verstraeten</vendor>
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java
index 9c10a51a7145..17d4f364a154 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java
@@ -23,27 +23,21 @@ import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.action.HgCommandResultNotifier;
import org.zmlx.hg4idea.command.HgPushCommand;
-import org.zmlx.hg4idea.command.HgTagBranch;
-import org.zmlx.hg4idea.command.HgTagBranchCommand;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.execution.HgCommandResultHandler;
+import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.ui.HgPushDialog;
-import org.zmlx.hg4idea.util.HgUtil;
-import java.util.Collections;
+import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-/**
- * @author Kirill Likhodedov
- */
public class HgPusher {
private static final Logger LOG = Logger.getInstance(HgPusher.class);
@@ -59,52 +53,27 @@ public class HgPusher {
myProject = project;
}
- public void showDialogAndPush(@Nullable final VirtualFile selectedRepo) {
- HgUtil.executeOnPooledThreadIfNeeded(new Runnable() {
- public void run() {
- final List<VirtualFile> repositories = HgUtil.getHgRepositories(myProject);
- if (repositories.isEmpty()) {
- VcsBalloonProblemNotifier.showOverChangesView(myProject, "No Mercurial repositories in the project", MessageType.ERROR);
- return;
- }
- VirtualFile firstRepo = repositories.get(0);
- final List<HgTagBranch> branches = getBranches(myProject, firstRepo);
- if (branches.isEmpty()) {
- return;
- }
- final AtomicReference<HgPushCommand> pushCommand = new AtomicReference<HgPushCommand>();
- UIUtil.invokeAndWaitIfNeeded(new Runnable() {
- @Override
- public void run() {
- final HgPushDialog dialog = new HgPushDialog(myProject, repositories, branches, selectedRepo);
- dialog.show();
- if (dialog.isOK()) {
- dialog.rememberSettings();
- pushCommand.set(preparePushCommand(myProject, dialog));
- new Task.Backgroundable(myProject, "Pushing...", false) {
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- if (pushCommand.get() != null) {
- push(myProject, pushCommand.get());
- }
- }
- }.queue();
- }
- }
- });
- }
- });
- }
+ public void showDialogAndPush (@NotNull Collection<HgRepository> repositories,@Nullable final HgRepository selectedRepo) {
- @NotNull
- public static List<HgTagBranch> getBranches(@NotNull Project project, @NotNull VirtualFile root) {
- HgCommandResult branchesResult = new HgTagBranchCommand(project, root).collectBranches();
- if (branchesResult == null) {
- new HgCommandResultNotifier(project)
- .notifyError(branchesResult, "Mercurial command failed", HgVcsMessages.message("hg4idea.branches.error.description"));
- return Collections.emptyList();
+ if (repositories.isEmpty()) {
+ VcsBalloonProblemNotifier.showOverChangesView(myProject, "No Mercurial repositories in the project", MessageType.ERROR);
+ return;
+ }
+ final AtomicReference<HgPushCommand> pushCommand = new AtomicReference<HgPushCommand>();
+ final HgPushDialog dialog = new HgPushDialog(myProject, repositories, selectedRepo);
+ dialog.show();
+ if (dialog.isOK()) {
+ dialog.rememberSettings();
+ pushCommand.set(preparePushCommand(myProject, dialog));
+ new Task.Backgroundable(myProject, "Pushing...", false) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ if (pushCommand.get() != null) {
+ push(myProject, pushCommand.get());
+ }
+ }
+ }.queue();
}
- return HgTagBranchCommand.parseResult(branchesResult);
}
private static void push(final Project project, HgPushCommand command) {
@@ -122,9 +91,11 @@ public class HgPusher {
String successDescription = String.format("Pushed %d %s [%s]", commitsNum, StringUtil.pluralize("commit", commitsNum),
repo.getPresentableName());
new HgCommandResultNotifier(project).notifySuccess(successTitle, successDescription);
- } else if (result.getExitValue() == NOTHING_TO_PUSH_EXIT_VALUE) {
+ }
+ else if (result.getExitValue() == NOTHING_TO_PUSH_EXIT_VALUE) {
new HgCommandResultNotifier(project).notifySuccess("", "Nothing to push");
- } else {
+ }
+ else {
new HgCommandResultNotifier(project).notifyError(result, "Push failed",
"Failed to push to [" + repo.getPresentableName() + "]");
}
@@ -133,10 +104,11 @@ public class HgPusher {
}
private static HgPushCommand preparePushCommand(Project project, HgPushDialog dialog) {
- final HgPushCommand command = new HgPushCommand(project, dialog.getRepository(), dialog.getTarget());
+ final HgPushCommand command = new HgPushCommand(project, dialog.getRepository().getRoot(), dialog.getTarget());
command.setRevision(dialog.getRevision());
command.setForce(dialog.isForce());
- command.setBranch(dialog.getBranch());
+ command.setBranchName(dialog.getBranch());
+ command.setBookmarkName(dialog.getBookmarkName());
command.setIsNewBranch(dialog.isNewBranch());
return command;
}
@@ -159,5 +131,4 @@ public class HgPusher {
}
return numberOfCommitsInAllSubrepos;
}
-
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java
index 3db5f19df3d9..9984facc8037 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java
@@ -23,6 +23,8 @@ import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgVcs;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.repo.HgRepositoryManager;
import org.zmlx.hg4idea.util.HgUtil;
import javax.swing.*;
@@ -47,10 +49,11 @@ abstract class HgAbstractGlobalAction extends AnAction {
return;
}
VirtualFile file = event.getData(CommonDataKeys.VIRTUAL_FILE);
- VirtualFile repo = file != null ? HgUtil.getHgRootOrNull(project, file) : null;
- List<VirtualFile> repos = HgUtil.getHgRepositories(project);
- if (!repos.isEmpty()) {
- execute(project, repos, repo);
+ HgRepositoryManager repositoryManager = HgUtil.getRepositoryManager(project);
+ HgRepository repo = file != null ? repositoryManager.getRepositoryForFile(file): HgUtil.getCurrentRepository(project);
+ List<HgRepository> repositories = repositoryManager.getRepositories();
+ if (!repositories.isEmpty()) {
+ execute(project, repositories, repo);
}
}
@@ -62,8 +65,8 @@ abstract class HgAbstractGlobalAction extends AnAction {
}
protected abstract void execute(@NotNull Project project,
- @NotNull Collection<VirtualFile> repositories,
- @Nullable VirtualFile selectedRepo);
+ @NotNull Collection<HgRepository> repositories,
+ @Nullable HgRepository selectedRepo);
public static void handleException(@Nullable Project project, @NotNull Exception e) {
handleException(project, "Error", e);
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAction.java
deleted file mode 100644
index 6660d104f49e..000000000000
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAction.java
+++ /dev/null
@@ -1,61 +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 org.zmlx.hg4idea.action;
-
-import com.intellij.openapi.actionSystem.AnAction;
-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;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.util.HgUtil;
-
-import javax.swing.*;
-
-/**
- * @author Kirill Likhodedov
- */
-public abstract class HgAction extends AnAction {
- protected HgAction() {
- }
-
- protected HgAction(Icon icon) {
- super(icon);
- }
-
- @Override
- public void actionPerformed(AnActionEvent event) {
- final DataContext dataContext = event.getDataContext();
- final Project project = CommonDataKeys.PROJECT.getData(dataContext);
- if (project == null) {
- return;
- }
- VirtualFile file = event.getData(CommonDataKeys.VIRTUAL_FILE);
- VirtualFile repo = file != null ? HgUtil.getHgRootOrNull(project, file) : null;
- execute(project, repo);
- }
-
- @Override
- public void update(AnActionEvent e) {
- boolean enabled = HgAbstractGlobalAction.isEnabled(e);
- e.getPresentation().setEnabled(enabled);
- }
-
- public abstract void execute(Project project, @Nullable VirtualFile selectedRepo);
-
-}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchAbstractAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchAbstractAction.java
new file mode 100644
index 000000000000..78b67013ed54
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchAbstractAction.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 org.zmlx.hg4idea.action;
+
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+import org.zmlx.hg4idea.repo.HgRepository;
+
+public abstract class HgBranchAbstractAction extends DumbAwareAction {
+ @NotNull protected final Project myProject;
+ @NotNull protected final HgRepository mySelectedRepository;
+ @NotNull protected final String myBranchName;
+
+ public HgBranchAbstractAction(@NotNull Project project, @NotNull String title,
+ @NotNull HgRepository selectedRepository,
+ @NotNull String branchName) {
+ super(title);
+ myProject = project;
+ mySelectedRepository = selectedRepository;
+ myBranchName = branchName;
+ }
+} \ No newline at end of file
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java
index b2b4f99fd946..01627240d8e4 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java
@@ -23,13 +23,10 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vcs.VcsException;
-import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.ContainerUtil;
@@ -39,14 +36,12 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
import org.zmlx.hg4idea.HgRevisionNumber;
-import org.zmlx.hg4idea.HgVcs;
-import org.zmlx.hg4idea.HgVcsMessages;
-import org.zmlx.hg4idea.command.*;
+import org.zmlx.hg4idea.command.HgBookmarkCommand;
+import org.zmlx.hg4idea.command.HgBranchCreateCommand;
+import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand;
import org.zmlx.hg4idea.execution.HgCommandException;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.execution.HgCommandResultHandler;
-import org.zmlx.hg4idea.provider.update.HgConflictResolver;
-import org.zmlx.hg4idea.provider.update.HgHeadMerger;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.ui.HgBookmarkDialog;
import org.zmlx.hg4idea.util.HgErrorUtil;
@@ -55,9 +50,6 @@ import java.util.*;
import static org.zmlx.hg4idea.util.HgUtil.*;
-/**
- * @author Nadya Zabrodina
- */
public class HgBranchPopupActions {
private final Project myProject;
@@ -80,9 +72,8 @@ public class HgBranchPopupActions {
popupGroup.addSeparator("Bookmarks");
List<String> bookmarkNames = getNamesWithoutHashes(myRepository.getBookmarks());
String currentBookmark = myRepository.getCurrentBookmark();
- Collections.sort(bookmarkNames);
for (String bookmark : bookmarkNames) {
- AnAction bookmarkAction = new BranchActions(myProject, bookmark, myRepository);
+ AnAction bookmarkAction = new BookmarkActions(myProject, myRepository, bookmark);
if (bookmark.equals(currentBookmark)) {
bookmarkAction.getTemplatePresentation().setIcon(PlatformIcons.CHECK_ICON);
}
@@ -94,7 +85,7 @@ public class HgBranchPopupActions {
Collections.sort(branchNamesList);
for (String branch : branchNamesList) {
if (!branch.equals(myRepository.getCurrentBranch())) { // don't show current branch in the list
- popupGroup.add(new BranchActions(myProject, branch, myRepository));
+ popupGroup.add(new HgCommonBranchActions(myProject, myRepository, branch));
}
}
return popupGroup;
@@ -160,17 +151,7 @@ public class HgBranchPopupActions {
if (bookmarkDialog.isOK()) {
try {
final String name = bookmarkDialog.getName();
- new HgBookmarkCreateCommand(myProject, myPreselectedRepo, name,
- bookmarkDialog.isActive()).execute(new HgCommandResultHandler() {
- @Override
- public void process(@Nullable HgCommandResult result) {
- getRepositoryManager(myProject).updateRepository(myPreselectedRepo);
- if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
- new HgCommandResultNotifier(myProject)
- .notifyError(result, "Creation failed", "Bookmark creation [" + name + "] failed");
- }
- }
- });
+ new HgBookmarkCommand(myProject, myPreselectedRepo, name).createBookmark(bookmarkDialog.isActive());
}
catch (HgCommandException exception) {
HgAbstractGlobalAction.handleException(myProject, exception);
@@ -229,7 +210,7 @@ public class HgBranchPopupActions {
public AnAction[] getChildren(@Nullable AnActionEvent e) {
List<AnAction> branchHeadActions = new ArrayList<AnAction>();
for (Hash hash : myHeads) {
- branchHeadActions.add(new BranchActions(myProject, hash.toShortString(), myRepository));
+ branchHeadActions.add(new HgCommonBranchActions(myProject, myRepository, hash.toShortString()));
}
return ContainerUtil.toArray(branchHeadActions, new AnAction[branchHeadActions.size()]);
}
@@ -246,117 +227,35 @@ public class HgBranchPopupActions {
}
}
-
/**
- * Actions available for branches.
+ * Actions available for bookmarks.
*/
- static class BranchActions extends ActionGroup {
-
- private final Project myProject;
- private String myBranchName;
- @NotNull private final HgRepository mySelectedRepository;
-
- BranchActions(@NotNull Project project, @NotNull String branchName,
- @NotNull HgRepository selectedRepository) {
- super("", true);
- myProject = project;
- myBranchName = branchName;
- mySelectedRepository = selectedRepository;
- getTemplatePresentation().setText(calcBranchText(), false); // no mnemonics
- }
+ static class BookmarkActions extends HgCommonBranchActions {
- @NotNull
- private String calcBranchText() {
- return myBranchName;
+ BookmarkActions(@NotNull Project project, @NotNull HgRepository selectedRepository, @NotNull String branchName) {
+ super(project, selectedRepository, branchName);
}
@NotNull
@Override
public AnAction[] getChildren(@Nullable AnActionEvent e) {
- return new AnAction[]{
- new UpdateToAction(myProject, mySelectedRepository, myBranchName),
- new MergeAction(myProject, mySelectedRepository, myBranchName)
- };
+ return ArrayUtil.append(super.getChildren(e), new DeleteBookmarkAction(myProject, mySelectedRepository, myBranchName));
}
- private static class MergeAction extends DumbAwareAction {
-
- private final Project myProject;
- private final HgRepository mySelectedRepository;
- private final String myBranchName;
+ private static class DeleteBookmarkAction extends HgBranchAbstractAction {
- public MergeAction(@NotNull Project project,
- @NotNull HgRepository selectedRepository,
- @NotNull String branchName) {
- super("Merge");
- myProject = project;
- mySelectedRepository = selectedRepository;
- myBranchName = branchName;
+ DeleteBookmarkAction(@NotNull Project project, @NotNull HgRepository selectedRepository, @NotNull String branchName) {
+ super(project, "Delete", selectedRepository, branchName);
}
@Override
public void actionPerformed(AnActionEvent e) {
- final UpdatedFiles updatedFiles = UpdatedFiles.create();
- final HgMergeCommand hgMergeCommand = new HgMergeCommand(myProject, mySelectedRepository.getRoot());
- hgMergeCommand.setBranch(myBranchName);
- final HgCommandResultNotifier notifier = new HgCommandResultNotifier(myProject);
- new Task.Backgroundable(myProject, "Merging changes...") {
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- try {
- new HgHeadMerger(myProject, hgMergeCommand)
- .merge(mySelectedRepository.getRoot(), updatedFiles, HgRevisionNumber.NULL_REVISION_NUMBER);
- new HgConflictResolver(myProject, updatedFiles).resolve(mySelectedRepository.getRoot());
- }
-
- catch (VcsException exception) {
- if (exception.isWarning()) {
- notifier.notifyWarning("Warning during merge", exception.getMessage());
- }
- else {
- notifier.notifyError(null, "Exception during merge", exception.getMessage());
- }
- }
- catch (Exception e1) {
- HgAbstractGlobalAction.handleException(myProject, e1);
- }
- }
- }.queue();
- }
- }
-
- private static class UpdateToAction extends DumbAwareAction {
-
- @NotNull private final Project myProject;
- @NotNull private final HgRepository mySelectedRepository;
- @NotNull private final String myBranch;
-
- public UpdateToAction(@NotNull Project project,
- @NotNull HgRepository selectedRepository,
- @NotNull String branch) {
- super("Update To");
- myProject = project;
- mySelectedRepository = selectedRepository;
- myBranch = branch;
- }
-
- @Override
- public void actionPerformed(AnActionEvent e) {
- final VirtualFile repository = mySelectedRepository.getRoot();
- final HgUpdateCommand hgUpdateCommand = new HgUpdateCommand(myProject, repository);
- hgUpdateCommand.setBranch(myBranch);
- new Task.Backgroundable(myProject, HgVcsMessages.message("action.hg4idea.updateTo.description", myBranch)) {
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- HgCommandResult result = hgUpdateCommand.execute();
- assert myProject != null; // myProject couldn't be null, see annotation for updateTo action
- if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
- new HgCommandResultNotifier(myProject).notifyError(result, "", "Update failed");
- new HgConflictResolver(myProject).resolve(repository);
- }
- myProject.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(myProject, null);
- }
- }.queue();
+ try {
+ new HgBookmarkCommand(myProject, mySelectedRepository.getRoot(), myBranchName).deleteBookmark();
+ }
+ catch (HgCommandException exception) {
+ HgAbstractGlobalAction.handleException(myProject, exception);
+ }
}
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java
index 61cf991c20a5..b8a10ed92116 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java
@@ -16,34 +16,18 @@
package org.zmlx.hg4idea.action;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.repo.HgRepository;
-import org.zmlx.hg4idea.util.HgUtil;
import java.util.Collection;
-/**
- * @author Nadya Zabrodina
- */
-
public class HgBranchesAction extends HgAbstractGlobalAction {
@Override
- protected void execute(@NotNull Project project, @NotNull Collection<VirtualFile> repositories, @Nullable VirtualFile selectedRepo) {
- HgRepository repository = null;
+ protected void execute(@NotNull Project project, @NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
if (selectedRepo != null) {
- repository = HgUtil.getRepositoryManager(project).getRepositoryForRoot(selectedRepo);
- }
- else {
- VirtualFile selectedRoot = HgUtil.getRootForSelectedFile(project);
- if (selectedRoot != null) {
- repository = HgUtil.getRepositoryManager(project).getRepositoryForRoot(selectedRoot);
- }
- }
- if (repository != null) {
- HgBranchPopup.getInstance(project, repository).asListPopup().showInFocusCenter();
+ HgBranchPopup.getInstance(project, selectedRepo).asListPopup().showInFocusCenter();
}
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommonBranchActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommonBranchActions.java
new file mode 100644
index 000000000000..992a26c6ab5e
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommonBranchActions.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.zmlx.hg4idea.action;
+
+import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.update.UpdatedFiles;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.HgVcs;
+import org.zmlx.hg4idea.HgVcsMessages;
+import org.zmlx.hg4idea.command.HgMergeCommand;
+import org.zmlx.hg4idea.command.HgUpdateCommand;
+import org.zmlx.hg4idea.execution.HgCommandResult;
+import org.zmlx.hg4idea.provider.update.HgConflictResolver;
+import org.zmlx.hg4idea.provider.update.HgHeadMerger;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.util.HgErrorUtil;
+
+public class HgCommonBranchActions extends ActionGroup {
+
+ @NotNull protected final Project myProject;
+ @NotNull protected String myBranchName;
+ @NotNull protected final HgRepository mySelectedRepository;
+
+ HgCommonBranchActions(@NotNull Project project, @NotNull HgRepository selectedRepository, @NotNull String branchName) {
+ super("", true);
+ myProject = project;
+ myBranchName = branchName;
+ mySelectedRepository = selectedRepository;
+ getTemplatePresentation().setText(myBranchName, false); // no mnemonics
+ }
+
+ @NotNull
+ @Override
+ public AnAction[] getChildren(@Nullable AnActionEvent e) {
+ return new AnAction[]{
+ new UpdateAction(myProject, mySelectedRepository, myBranchName),
+ new MergeAction(myProject, mySelectedRepository, myBranchName)
+ };
+ }
+
+ private static class MergeAction extends HgBranchAbstractAction {
+
+ public MergeAction(@NotNull Project project,
+ @NotNull HgRepository selectedRepository,
+ @NotNull String branchName) {
+ super(project, "Merge", selectedRepository, branchName);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final UpdatedFiles updatedFiles = UpdatedFiles.create();
+ final HgMergeCommand hgMergeCommand = new HgMergeCommand(myProject, mySelectedRepository.getRoot());
+ hgMergeCommand.setRevision(myBranchName);//there is no difference between branch or revision or bookmark as parameter to merge,
+ // we need just a string
+ final HgCommandResultNotifier notifier = new HgCommandResultNotifier(myProject);
+ new Task.Backgroundable(myProject, "Merging changes...") {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ try {
+ new HgHeadMerger(myProject, hgMergeCommand)
+ .merge(mySelectedRepository.getRoot());
+ new HgConflictResolver(myProject, updatedFiles).resolve(mySelectedRepository.getRoot());
+ }
+
+ catch (VcsException exception) {
+ if (exception.isWarning()) {
+ notifier.notifyWarning("Warning during merge", exception.getMessage());
+ }
+ else {
+ notifier.notifyError(null, "Exception during merge", exception.getMessage());
+ }
+ }
+ catch (Exception e1) {
+ HgAbstractGlobalAction.handleException(myProject, e1);
+ }
+ }
+ }.queue();
+ }
+ }
+
+ private static class UpdateAction extends HgBranchAbstractAction {
+
+ public UpdateAction(@NotNull Project project,
+ @NotNull HgRepository selectedRepository,
+ @NotNull String branchName) {
+ super(project, "Update", selectedRepository, branchName);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final VirtualFile repository = mySelectedRepository.getRoot();
+ final HgUpdateCommand hgUpdateCommand = new HgUpdateCommand(myProject, repository);
+ hgUpdateCommand.setBranch(myBranchName);
+ new Task.Backgroundable(myProject, HgVcsMessages.message("action.hg4idea.updateTo.description", myBranchName)) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ HgCommandResult result = hgUpdateCommand.execute();
+ assert myProject != null; // myProject couldn't be null, see annotation for updateTo action
+ if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
+ new HgCommandResultNotifier(myProject).notifyError(result, "", "Update failed");
+ new HgConflictResolver(myProject).resolve(repository);
+ }
+ myProject.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(myProject, null);
+ }
+ }.queue();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java
index 1aec1a0e56e4..5c97e3ca9f39 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java
@@ -13,13 +13,13 @@
package org.zmlx.hg4idea.action;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.command.HgTagCreateCommand;
import org.zmlx.hg4idea.execution.HgCommandException;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.execution.HgCommandResultHandler;
+import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.ui.HgTagDialog;
import org.zmlx.hg4idea.util.HgErrorUtil;
@@ -28,11 +28,10 @@ import java.util.Collection;
public class HgCreateTagAction extends HgAbstractGlobalAction {
public void execute(@NotNull final Project project,
- @NotNull Collection<VirtualFile> repos,
- @Nullable VirtualFile selectedRepo,
+ @NotNull Collection<HgRepository> repositories,
+ @Nullable HgRepository selectedRepo,
@Nullable final String reference) {
- final HgTagDialog dialog = new HgTagDialog(project);
- dialog.setRoots(repos, selectedRepo);
+ final HgTagDialog dialog = new HgTagDialog(project, repositories, selectedRepo);
dialog.show();
if (dialog.isOK()) {
try {
@@ -52,7 +51,9 @@ public class HgCreateTagAction extends HgAbstractGlobalAction {
}
}
- protected void execute(@NotNull final Project project, @NotNull Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo) {
- execute(project, repos, selectedRepo, null);
+ protected void execute(@NotNull final Project project,
+ @NotNull Collection<HgRepository> repositories,
+ @Nullable HgRepository selectedRepo) {
+ execute(project, repositories, selectedRepo, null);
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagFromLogAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagFromLogAction.java
index 18a42d735046..03f6f951cea7 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagFromLogAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagFromLogAction.java
@@ -19,15 +19,12 @@ import com.intellij.vcs.log.VcsFullCommitDetails;
import org.jetbrains.annotations.NotNull;
import org.zmlx.hg4idea.repo.HgRepository;
-import java.util.Arrays;
+import java.util.Collections;
-/**
- * @author Nadya Zabrodina
- */
public class HgCreateTagFromLogAction extends HgLogSingleCommitAction {
@Override
protected void actionPerformed(@NotNull HgRepository repository, @NotNull VcsFullCommitDetails commit) {
String revisionHash = commit.getHash().asString();
- new HgCreateTagAction().execute(repository.getProject(), Arrays.asList(repository.getRoot()), repository.getRoot(), revisionHash);
+ new HgCreateTagAction().execute(repository.getProject(), Collections.singleton(repository), repository, revisionHash);
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java
index fe022bcfb775..87c907d76d59 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java
@@ -18,56 +18,37 @@ package org.zmlx.hg4idea.action;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.HgRevisionNumber;
-import org.zmlx.hg4idea.HgVcsMessages;
import org.zmlx.hg4idea.command.HgMergeCommand;
-import org.zmlx.hg4idea.command.HgTagBranch;
import org.zmlx.hg4idea.execution.HgCommandException;
import org.zmlx.hg4idea.provider.update.HgConflictResolver;
import org.zmlx.hg4idea.provider.update.HgHeadMerger;
+import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.ui.HgMergeDialog;
-import org.zmlx.hg4idea.util.HgBranchesAndTags;
-import org.zmlx.hg4idea.util.HgUiUtil;
import java.util.Collection;
-/**
- * @author Nadya Zabrodina
- */
public class HgMerge extends HgAbstractGlobalAction {
@Override
public void execute(@NotNull final Project project,
- @NotNull final Collection<VirtualFile> repos,
- @Nullable final VirtualFile selectedRepo) {
- HgUiUtil.loadBranchesInBackgroundableAndExecuteAction(project, repos, new Consumer<HgBranchesAndTags>() {
-
- @Override
- public void consume(HgBranchesAndTags info) {
- showMergeDialogAndExecute(project, repos, selectedRepo, info);
- }
- });
- }
-
- private void showMergeDialogAndExecute(final Project project,
- Collection<VirtualFile> repos,
- @Nullable VirtualFile selectedRepo, HgBranchesAndTags branchesAndTags) {
- final HgMergeDialog mergeDialog = new HgMergeDialog(project, repos, selectedRepo, branchesAndTags);
+ @NotNull final Collection<HgRepository> repos,
+ @Nullable final HgRepository selectedRepo) {
+ final HgMergeDialog mergeDialog = new HgMergeDialog(project, repos, selectedRepo);
mergeDialog.show();
if (mergeDialog.isOK()) {
+ final String targetValue = mergeDialog.getTargetValue();
+ final VirtualFile repoRoot = mergeDialog.getRepository().getRoot();
new Task.Backgroundable(project, "Merging changes...") {
@Override
public void run(@NotNull ProgressIndicator indicator) {
try {
- executeMerge(mergeDialog, project);
- markDirtyAndHandleErrors(project, mergeDialog.getRepository());
+ executeMerge(project, repoRoot, targetValue);
+ markDirtyAndHandleErrors(project, repoRoot);
}
catch (HgCommandException e) {
handleException(project, e);
@@ -77,63 +58,26 @@ public class HgMerge extends HgAbstractGlobalAction {
}
}
- private static void executeMerge(final HgMergeDialog dialog, final Project project) throws HgCommandException {
+
+ private static void executeMerge(@NotNull final Project project, @NotNull VirtualFile repo, @NotNull String targetValue)
+ throws HgCommandException {
UpdatedFiles updatedFiles = UpdatedFiles.create();
HgCommandResultNotifier notifier = new HgCommandResultNotifier(project);
- final VirtualFile repo = dialog.getRepository();
HgMergeCommand hgMergeCommand = new HgMergeCommand(project, repo);
+ hgMergeCommand.setRevision(targetValue);
- HgRevisionNumber incomingRevision = null;
- HgTagBranch branch = dialog.getBranch();
- if (branch != null) {
- hgMergeCommand.setBranch(branch.getName());
- incomingRevision = branch.getHead();
- }
-
- HgTagBranch tag = dialog.getTag();
- if (tag != null) {
- hgMergeCommand.setRevision(tag.getName());
- incomingRevision = tag.getHead();
- }
-
- HgTagBranch bookmark = dialog.getBookmark();
- if (bookmark != null) {
- hgMergeCommand.setRevision(bookmark.getName());
- incomingRevision = bookmark.getHead();
- }
-
- String revision = dialog.getRevision();
- if (revision != null) {
- hgMergeCommand.setRevision(revision);
- incomingRevision = HgRevisionNumber.getLocalInstance(revision);
- }
-
- HgRevisionNumber otherHead = dialog.getOtherHead();
- if (otherHead != null) {
- String changeset = otherHead.getChangeset();
- hgMergeCommand.setRevision(StringUtil.isEmptyOrSpaces(changeset) ? otherHead.getRevision() : changeset);
- incomingRevision = otherHead;
+ try {
+ new HgHeadMerger(project, hgMergeCommand).merge(repo);
+ new HgConflictResolver(project, updatedFiles).resolve(repo);
}
-
- if (incomingRevision != null) {
- try {
- new HgHeadMerger(project, hgMergeCommand)
- .merge(repo, updatedFiles, incomingRevision);
- new HgConflictResolver(project, updatedFiles).resolve(repo);
+ catch (VcsException e) {
+ if (e.isWarning()) {
+ notifier.notifyWarning("Warning during merge", e.getMessage());
}
- catch (VcsException e) {
- if (e.isWarning()) {
- notifier.notifyWarning("Warning during merge", e.getMessage());
- }
- else {
- notifier.notifyError(null, "Exception during merge", e.getMessage());
- }
+ else {
+ notifier.notifyError(null, "Exception during merge", e.getMessage());
}
}
- else {
- //noinspection ThrowableInstanceNeverThrown
- notifier.notifyError(null, "Merge error", HgVcsMessages.message("hg4idea.error.invalidTarget"));
- }
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java
index 136a50e69809..557d3cfab286 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java
@@ -16,10 +16,10 @@ import com.intellij.icons.AllIcons;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.command.HgPullCommand;
+import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.ui.HgPullDialog;
import java.util.Collection;
@@ -30,9 +30,8 @@ public class HgPullAction extends HgAbstractGlobalAction {
}
@Override
- protected void execute(@NotNull final Project project, @NotNull Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo) {
- final HgPullDialog dialog = new HgPullDialog(project);
- dialog.setRoots(repos, selectedRepo);
+ protected void execute(@NotNull final Project project, @NotNull Collection<HgRepository> repos, @Nullable HgRepository selectedRepo) {
+ final HgPullDialog dialog = new HgPullDialog(project, repos, selectedRepo);
dialog.show();
if (dialog.isOK()) {
dialog.rememberSettings();
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPushAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPushAction.java
index ae6206c7a253..1b5704f1d0f4 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPushAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPushAction.java
@@ -14,18 +14,22 @@ package org.zmlx.hg4idea.action;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgPusher;
+import org.zmlx.hg4idea.repo.HgRepository;
-public class HgPushAction extends HgAction {
+import java.util.Collection;
+
+public class HgPushAction extends HgAbstractGlobalAction {
public HgPushAction() {
super(AllIcons.Actions.Commit);
}
@Override
- public void execute(final Project project, @Nullable final VirtualFile selectedRepo) {
- new HgPusher(project).showDialogAndPush(selectedRepo);
+ public void execute(@NotNull final Project project,
+ @NotNull Collection<HgRepository> repositories,
+ @Nullable final HgRepository selectedRepo) {
+ new HgPusher(project).showDialogAndPush(repositories, selectedRepo);
}
-
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgRunConflictResolverAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgRunConflictResolverAction.java
index 3be82ada2a8d..938413e95356 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgRunConflictResolverAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgRunConflictResolverAction.java
@@ -15,11 +15,12 @@ package org.zmlx.hg4idea.action;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgVcsMessages;
import org.zmlx.hg4idea.provider.update.HgConflictResolver;
+import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.ui.HgRunConflictResolverDialog;
import java.util.Collection;
@@ -27,39 +28,26 @@ import java.util.Collection;
public class HgRunConflictResolverAction extends HgAbstractGlobalAction {
@Override
- public void execute(@NotNull final Project project, @NotNull Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo) {
- final VirtualFile repository;
- if (repos.size() > 1) {
- repository = letUserSelectRepository(repos, project, selectedRepo);
- }
- else if (repos.size() == 1) {
- repository = repos.iterator().next();
- }
- else {
- repository = null;
- }
+ public void execute(@NotNull final Project project, @NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
+ final HgRepository repository = repositories.size() > 1 ? letUserSelectRepository(project, repositories, selectedRepo) :
+ ContainerUtil.getFirstItem(repositories);
if (repository != null) {
new Task.Backgroundable(project, HgVcsMessages.message("action.hg4idea.run.conflict.resolver.description")) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
- new HgConflictResolver(project).resolve(repository);
- markDirtyAndHandleErrors(project, repository);
+ new HgConflictResolver(project).resolve(repository.getRoot());
+ markDirtyAndHandleErrors(project, repository.getRoot());
}
}.queue();
}
}
-
- private static VirtualFile letUserSelectRepository(Collection<VirtualFile> repos, Project project, @Nullable VirtualFile selectedRepo) {
- HgRunConflictResolverDialog dialog = new HgRunConflictResolverDialog(project);
- dialog.setRoots(repos, selectedRepo);
+ @Nullable
+ private static HgRepository letUserSelectRepository(@NotNull Project project, @NotNull Collection<HgRepository> repositories,
+ @Nullable HgRepository selectedRepo) {
+ HgRunConflictResolverDialog dialog = new HgRunConflictResolverDialog(project, repositories, selectedRepo);
dialog.show();
- if (dialog.isOK()) {
- return dialog.getRepository();
- }
- else {
- return null;
- }
+ return dialog.isOK() ? dialog.getRepository() : null;
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java
index 1a2cdeae8b55..7e1025921234 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java
@@ -17,61 +17,43 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgVcsMessages;
import org.zmlx.hg4idea.command.HgUpdateCommand;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.provider.update.HgConflictResolver;
+import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.ui.HgUpdateToDialog;
-import org.zmlx.hg4idea.util.HgBranchesAndTags;
import org.zmlx.hg4idea.util.HgErrorUtil;
-import org.zmlx.hg4idea.util.HgUiUtil;
import java.util.Collection;
public class HgUpdateToAction extends HgAbstractGlobalAction {
- protected void execute(@NotNull final Project project,
- @NotNull final Collection<VirtualFile> repos,
- @Nullable final VirtualFile selectedRepo) {
- HgUiUtil.loadBranchesInBackgroundableAndExecuteAction(project, repos, new Consumer<HgBranchesAndTags>() {
- @Override
- public void consume(HgBranchesAndTags info) {
- showUpdateDialogAndExecute(project, repos, selectedRepo, info);
- }
- });
- }
-
- private static void showUpdateDialogAndExecute(@NotNull final Project project,
- @NotNull Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo,
- @NotNull HgBranchesAndTags branchesAndTags) {
- final HgUpdateToDialog dialog = new HgUpdateToDialog(project);
- dialog.setRoots(repos, selectedRepo, branchesAndTags);
+ @Override
+ protected void execute(@NotNull Project project, @NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
+ final HgUpdateToDialog dialog = new HgUpdateToDialog(project, repositories, selectedRepo);
dialog.show();
if (dialog.isOK()) {
FileDocumentManager.getInstance().saveAllDocuments();
- final String updateToValue = dialog.isBranchSelected()
- ? dialog.getBranch().getName()
- : dialog.isBookmarkSelected()
- ? dialog.getBookmark().getName()
- : dialog.isTagSelected() ? dialog.getTag().getName() : dialog.getRevision();
+ final String updateToValue = dialog.getTargetValue();
+ boolean clean = dialog.isRemoveLocalChanges();
String title = HgVcsMessages.message("hg4idea.progress.updatingTo", updateToValue);
- runUpdateToInBackground(project, title, dialog.getRepository(), updateToValue, dialog.isRemoveLocalChanges());
+ runUpdateToInBackground(project, title, dialog.getRepository().getRoot(), updateToValue, clean);
}
}
public static void runUpdateToInBackground(@NotNull final Project project,
@NotNull String title,
@NotNull final VirtualFile root,
- @NotNull final String updateToNameOrRevision,
+ @NotNull final String updateToValue,
final boolean clean) {
new Task.Backgroundable(project, title) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
final HgUpdateCommand command = new HgUpdateCommand(project, root);
- command.setRevision(updateToNameOrRevision);
+ command.setRevision(updateToValue);
command.setClean(clean);
HgCommandResult result = command.execute();
new HgConflictResolver(project).resolve(root);
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBookmarkCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBookmarkCommand.java
new file mode 100644
index 000000000000..21b4edd2d7cb
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBookmarkCommand.java
@@ -0,0 +1,65 @@
+package org.zmlx.hg4idea.command;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.action.HgCommandResultNotifier;
+import org.zmlx.hg4idea.execution.HgCommandException;
+import org.zmlx.hg4idea.execution.HgCommandExecutor;
+import org.zmlx.hg4idea.execution.HgCommandResult;
+import org.zmlx.hg4idea.execution.HgCommandResultHandler;
+import org.zmlx.hg4idea.util.HgErrorUtil;
+
+import java.util.List;
+
+import static org.zmlx.hg4idea.util.HgUtil.getRepositoryManager;
+
+public class HgBookmarkCommand {
+ @NotNull private final Project myProject;
+ @NotNull private final VirtualFile myRepo;
+ @Nullable private final String myBookmarkName;
+ @NotNull private final HgCommandResultHandler myBookmarkResultHandler;
+
+ public HgBookmarkCommand(@NotNull Project project,
+ @NotNull VirtualFile repo,
+ @Nullable String bookmarkName) {
+ myProject = project;
+ myRepo = repo;
+ myBookmarkName = bookmarkName;
+ myBookmarkResultHandler = new HgCommandResultHandler() {
+ @Override
+ public void process(@Nullable HgCommandResult result) {
+ getRepositoryManager(myProject).updateRepository(myRepo);
+ if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
+ new HgCommandResultNotifier(myProject)
+ .notifyError(result, "Hg Error", "Hg bookmark command failed for " + myBookmarkName);
+ }
+ }
+ };
+ }
+
+ public void createBookmark(boolean isActive) throws HgCommandException {
+ if (isActive) {
+ executeBookmarkCommand();
+ }
+ else {
+ executeBookmarkCommand("--inactive");
+ }
+ }
+
+ public void deleteBookmark() throws HgCommandException {
+ executeBookmarkCommand("-d"); //delete
+ }
+
+ private void executeBookmarkCommand(@NotNull String... args) throws HgCommandException {
+ if (StringUtil.isEmptyOrSpaces(myBookmarkName)) {
+ throw new HgCommandException("bookmark name is empty");
+ }
+ List<String> arguments = ContainerUtil.newArrayList(args);
+ arguments.add(myBookmarkName);
+ new HgCommandExecutor(myProject).execute(myRepo, "bookmark", arguments, myBookmarkResultHandler);
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBookmarkCreateCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBookmarkCreateCommand.java
deleted file mode 100644
index 89442efbc35e..000000000000
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBookmarkCreateCommand.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.zmlx.hg4idea.command;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.execution.HgCommandException;
-import org.zmlx.hg4idea.execution.HgCommandExecutor;
-import org.zmlx.hg4idea.execution.HgCommandResultHandler;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Nadya Zabrodina
- */
-public class HgBookmarkCreateCommand {
- @NotNull private final Project myProject;
- @NotNull private final VirtualFile myRepo;
- @Nullable private final String myBookmarkName;
- private final boolean isActive;
-
- public HgBookmarkCreateCommand(@NotNull Project project,
- @NotNull VirtualFile repo,
- @Nullable String bookmarkName,
- boolean active) {
- myProject = project;
- myRepo = repo;
- myBookmarkName = bookmarkName;
- isActive = active;
- }
-
- public void execute(@Nullable HgCommandResultHandler resultHandler) throws HgCommandException {
- if (StringUtil.isEmptyOrSpaces(myBookmarkName)) {
- throw new HgCommandException("bookmark name is empty");
- }
- List<String> arguments = new ArrayList<String>();
- arguments.add(myBookmarkName);
- if (!isActive) {
- arguments.add("--inactive");
- }
- new HgCommandExecutor(myProject).execute(myRepo, "bookmark", arguments, resultHandler);
- }
-}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTagBranchCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBranchesCommand.java
index 7c1aa067b20d..430e7e10b58d 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTagBranchCommand.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBranchesCommand.java
@@ -17,72 +17,31 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.HgRevisionNumber;
import org.zmlx.hg4idea.execution.HgCommandExecutor;
import org.zmlx.hg4idea.execution.HgCommandResult;
-import java.util.LinkedList;
-import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class HgTagBranchCommand {
+public class HgBranchesCommand {
private static final Pattern BRANCH_LINE = Pattern.compile("(.+)\\s([0-9]+):([0-9a-f]+).*");
private static final int NAME_INDEX = 1;
- private static final int REVISION_INDEX = 2;
- private static final int CHANGESET_INDEX = 3;
private final Project project;
private final VirtualFile repo;
- public HgTagBranchCommand(Project project, @NotNull VirtualFile repo) {
+ public HgBranchesCommand(Project project, @NotNull VirtualFile repo) {
this.project = project;
this.repo = repo;
}
@Nullable
- public String getCurrentBranch() {
- final HgCommandExecutor executor = new HgCommandExecutor(project);
- executor.setSilent(true);
- HgCommandResult result = executor.executeInCurrentThread(repo, "branch", null);
- if (result == null) {
- return null;
- }
- List<String> output = result.getOutputLines();
- if (output == null || output.isEmpty()) {
- return null;
- }
- return output.get(0).trim();
- }
-
public HgCommandResult collectBranches() {
return new HgCommandExecutor(project).executeInCurrentThread(repo, "branches", null);
}
- public HgCommandResult collectTags() {
- return new HgCommandExecutor(project).executeInCurrentThread(repo, "tags", null);
- }
-
- public HgCommandResult collectBookmarks() {
- return new HgCommandExecutor(project).executeInCurrentThread(repo, "bookmarks", null);
- }
-
- public static List<HgTagBranch> parseResult(@NotNull HgCommandResult result) {
- List<HgTagBranch> branches = new LinkedList<HgTagBranch>();
- for (final String line : result.getOutputLines()) {
- Matcher matcher = BRANCH_LINE.matcher(line);
- if (matcher.matches()) {
- HgRevisionNumber hgRevisionNumber = HgRevisionNumber.getInstance(
- matcher.group(REVISION_INDEX), matcher.group(CHANGESET_INDEX)
- );
- branches.add(new HgTagBranch(matcher.group(NAME_INDEX).trim(), line.trim(), hgRevisionNumber));
- }
- }
- return branches;
- }
-
@NotNull
public static Set<String> collectNames(@NotNull HgCommandResult result) {
Set<String> branches = new HashSet<String>();
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgMergeCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgMergeCommand.java
index d8d70f0c5cc8..ad10a373de4e 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgMergeCommand.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgMergeCommand.java
@@ -15,6 +15,7 @@ package org.zmlx.hg4idea.command;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.execution.HgCommandExecutor;
@@ -26,22 +27,17 @@ import java.util.List;
public class HgMergeCommand {
- private final Project project;
- private final VirtualFile repo;
+ @NotNull private final Project project;
+ @NotNull private final VirtualFile repo;
- private String branch;
private String revision;
- public HgMergeCommand(Project project, VirtualFile repo) {
+ public HgMergeCommand(@NotNull Project project, @NotNull VirtualFile repo) {
this.project = project;
this.repo = repo;
}
- public void setBranch(String branch) {
- this.branch = branch;
- }
-
- public void setRevision(String revision) {
+ public void setRevision(@NotNull String revision) {
this.revision = revision;
}
@@ -53,13 +49,10 @@ public class HgMergeCommand {
if (!StringUtil.isEmptyOrSpaces(revision)) {
arguments.add("--rev");
arguments.add(revision);
- } else if (!StringUtil.isEmptyOrSpaces(branch)) {
- arguments.add(branch);
}
final HgCommandResult result =
commandExecutor.executeInCurrentThread(repo, "merge", arguments, new HgDeleteModifyPromptHandler());
project.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(project, null);
return result;
}
-
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgPushCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgPushCommand.java
index 357fa891201a..16748462a45f 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgPushCommand.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgPushCommand.java
@@ -33,7 +33,8 @@ public class HgPushCommand {
private String myRevision;
private boolean myForce;
- private HgTagBranch myBranch;
+ private String myBranchName;
+ private String myBookmarkName;
private boolean myIsNewBranch;
public HgPushCommand(Project project, @NotNull VirtualFile repo, String destination) {
@@ -50,13 +51,17 @@ public class HgPushCommand {
myForce = force;
}
- public void setBranch(HgTagBranch branch) {
- myBranch = branch;
+ public void setBranchName(String branchName) {
+ myBranchName = branchName;
}
public void setIsNewBranch(boolean isNewBranch) {
- myIsNewBranch = isNewBranch;
- }
+ myIsNewBranch = isNewBranch;
+ }
+
+ public void setBookmarkName(String bookmark) {
+ myBookmarkName = bookmark;
+ }
public void execute(final HgCommandResultHandler resultHandler) {
final List<String> arguments = new LinkedList<String>();
@@ -64,15 +69,19 @@ public class HgPushCommand {
arguments.add("-r");
arguments.add(myRevision);
}
- if (myBranch != null) {
+ if (myBranchName != null) {
if (myIsNewBranch) {
arguments.add("--new-branch");
}
else {
arguments.add("-b");
- arguments.add(myBranch.getName());
+ arguments.add(myBranchName);
}
}
+ if (!StringUtil.isEmptyOrSpaces(myBookmarkName)) {
+ arguments.add("-B");
+ arguments.add(myBookmarkName);
+ }
if (myForce) {
arguments.add("-f");
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTagBranch.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTagBranch.java
deleted file mode 100644
index cf4325afdcb4..000000000000
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgTagBranch.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2008-2010 Victor Iacoban
-//
-// 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.zmlx.hg4idea.command;
-
-import com.intellij.openapi.util.text.StringUtil;
-import org.zmlx.hg4idea.HgRevisionNumber;
-
-public final class HgTagBranch {
-
- private static final int SPACINGAFTERFIRSTLETTER = 20;
-
- private final String name;
- private final String description;
- private final HgRevisionNumber head;
- private final String presentation;
-
- public HgTagBranch(String name, String description, HgRevisionNumber head) {
- this.name = name;
- this.description = description;
- this.head = head;
- int whitespaceNum = SPACINGAFTERFIRSTLETTER - name.length();
- String presentationName = whitespaceNum <= 0 ? name.substring(0, SPACINGAFTERFIRSTLETTER - 4).concat("...") : name;
- presentation = String.format("%s%s%s", presentationName, whitespaceNum > 0 ? StringUtil.repeatSymbol(' ', whitespaceNum) : " ", head);
- }
-
- public String getName() {
- return name;
- }
-
- public String getDescription() {
- return description;
- }
-
- public HgRevisionNumber getHead() {
- return head;
- }
-
- @Override
- public String toString() {
- return presentation;
- }
-}
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 aaf9e9dd1c8b..dec0e720fcdb 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java
@@ -40,6 +40,8 @@ import org.zmlx.hg4idea.command.*;
import org.zmlx.hg4idea.execution.HgCommandException;
import org.zmlx.hg4idea.execution.HgCommandExecutor;
import org.zmlx.hg4idea.execution.HgCommandResult;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.repo.HgRepositoryManager;
import org.zmlx.hg4idea.util.HgUtil;
import java.util.*;
@@ -125,9 +127,12 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
// push if needed
if (myNextCommitIsPushed && exceptions.isEmpty()) {
final VirtualFile preselectedRepo = repositoriesMap.size() == 1 ? repositoriesMap.keySet().iterator().next() : null;
+ HgRepositoryManager repositoryManager = HgUtil.getRepositoryManager(myProject);
+ final HgRepository repo = preselectedRepo != null ? repositoryManager.getRepositoryForFile(preselectedRepo) : null;
+ final Collection<HgRepository> repositories = repositoryManager.getRepositories();
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
- new HgPusher(myProject).showDialogAndPush(preselectedRepo);
+ new HgPusher(myProject).showDialogAndPush(repositories, repo);
}
});
}
@@ -264,31 +269,33 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
public HgCommitAdditionalComponent(@NotNull Project project, @NotNull CheckinProjectPanel panel) {
super(project, panel);
HgVcs myVcs = HgVcs.getInstance(myProject);
- if (myVcs != null && !myVcs.getVersion().isAmendSupported()) {
- myAmend.setEnabled(false);
- }
+ myAmend.setEnabled(myVcs != null && myVcs.getVersion().isAmendSupported());
}
+ @Override
public void refresh() {
super.refresh();
myNextCommitAmend = false;
}
+ @Override
public void saveState() {
myNextCommitAmend = myAmend.isSelected();
}
+ @Override
public void restoreState() {
myNextCommitAmend = false;
}
@NotNull
@Override
- protected Collection<VirtualFile> getRoots() {
- return HgUtil.getHgRepositories(myProject);
+ protected Set<VirtualFile> getVcsRoots(@NotNull Collection<FilePath> filePaths) {
+ return HgUtil.hgRoots(myProject, filePaths);
}
@Nullable
+ @Override
protected String getLastCommitMessage(@NotNull VirtualFile repo) throws VcsException {
HgCommandExecutor commandExecutor = new HgCommandExecutor(myProject);
List<String> args = new ArrayList<String>();
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgHeadMerger.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgHeadMerger.java
index 15ab366f1001..a9df96b07ca3 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgHeadMerger.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgHeadMerger.java
@@ -15,8 +15,6 @@ package org.zmlx.hg4idea.provider.update;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.VcsException;
-import com.intellij.openapi.vcs.history.VcsRevisionNumber;
-import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.zmlx.hg4idea.command.HgMergeCommand;
@@ -38,11 +36,9 @@ public final class HgHeadMerger {
this.hgMergeCommand = hgMergeCommand;
}
- public HgCommandResult merge(VirtualFile repo, UpdatedFiles updatedFiles,
- VcsRevisionNumber revisionNumber) throws VcsException {
+ public HgCommandResult merge(VirtualFile repo) throws VcsException {
HgCommandResult commandResult = ensureSuccess(hgMergeCommand.execute());
-
try {
HgUtil.markDirectoryDirty(project, repo);
}
@@ -61,5 +57,4 @@ public final class HgHeadMerger {
LOG.info(msg, e);
throw new VcsException(msg);
}
-
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java
index b0b4c7a0ab56..355405f33e7f 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java
@@ -113,7 +113,7 @@ public class HgRegularUpdater implements HgUpdater {
abortOnMultiplePulledHeads(pulledBranchHeads);
abortOnMultipleLocalHeads(remainingOriginalBranchHeads);
- HgCommandResult mergeResult = doMerge(updatedFiles, indicator, pulledBranchHeads.get(0));
+ HgCommandResult mergeResult = doMerge(indicator);
if (shouldCommitAfterMerge()) {
commitOrWarnAboutConflicts(warnings, mergeResult);
@@ -198,15 +198,13 @@ public class HgRegularUpdater implements HgUpdater {
}
}
- private HgCommandResult doMerge(UpdatedFiles updatedFiles,
- ProgressIndicator indicator,
- HgRevisionNumber headToMerge) throws VcsException {
+ private HgCommandResult doMerge(ProgressIndicator indicator) throws VcsException {
indicator.setText2(HgVcsMessages.message("hg4idea.update.progress.merging"));
HgMergeCommand mergeCommand = new HgMergeCommand(project, repoRoot);
//do not explicitly set the revision, that way mercurial itself checks that there are exactly
//two heads in this branch
// mergeCommand.setRevision(headToMerge.getRevision());
- return new HgHeadMerger(project, mergeCommand).merge(repoRoot, updatedFiles, headToMerge);
+ return new HgHeadMerger(project, mergeCommand).merge(repoRoot);
}
private void abortOnLocalChanges() throws VcsException {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
index bef1b6854d1b..fb0036185ebf 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
import org.zmlx.hg4idea.HgVcs;
-import org.zmlx.hg4idea.command.HgTagBranchCommand;
+import org.zmlx.hg4idea.command.HgBranchesCommand;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.util.HgUtil;
@@ -162,13 +162,13 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
// Then blinking and do not work properly;
if (!Disposer.isDisposed(getProject()) && !currentInfo.equals(myInfo)) {
myInfo = currentInfo;
- HgCommandResult branchCommandResult = new HgTagBranchCommand(getProject(), getRoot()).collectBranches();
+ HgCommandResult branchCommandResult = new HgBranchesCommand(getProject(), getRoot()).collectBranches();
if (branchCommandResult == null || branchCommandResult.getExitValue() != 0) {
LOG.warn("Could not collect hg opened branches."); // hg executable is not valid
myOpenedBranches = myInfo.getBranches().keySet();
}
else {
- myOpenedBranches = HgTagBranchCommand.collectNames(branchCommandResult);
+ myOpenedBranches = HgBranchesCommand.collectNames(branchCommandResult);
}
getProject().getMessageBus().syncPublisher(HgVcs.STATUS_TOPIC).update(getProject(), getRoot());
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateToDialog.form b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCommonDialogWithChoices.form
index 0fe5286fdb5a..1e932fe8a2ba 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateToDialog.form
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCommonDialogWithChoices.form
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.zmlx.hg4idea.ui.HgUpdateToDialog">
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.zmlx.hg4idea.ui.HgCommonDialogWithChoices">
<grid id="27dc6" binding="contentPanel" layout-manager="GridLayoutManager" row-count="4" 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="500" height="400"/>
+ <xy x="22" y="20" width="498" height="291"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<vspacer id="84392">
<constraints>
- <grid row="3" 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="3" column="0" row-span="1" col-span="1" vsize-policy="2" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<hspacer id="af9e5">
@@ -23,10 +23,14 @@
<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>
+ <enabled value="false"/>
<text value="&amp;Overwrite locally modified files (no backup)"/>
</properties>
+ <clientProperties>
+ <html.disable class="java.lang.Boolean" value="false"/>
+ </clientProperties>
</component>
- <grid id="814c5" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="814c5" binding="myBranchesBorderPanel" layout-manager="GridLayoutManager" row-count="4" 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="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -35,7 +39,7 @@
<clientProperties>
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
</clientProperties>
- <border type="none" title="Switch to"/>
+ <border type="none"/>
<children>
<component id="674b0" class="javax.swing.JRadioButton" binding="branchOption">
<constraints>
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCommonDialogWithChoices.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCommonDialogWithChoices.java
new file mode 100644
index 000000000000..4c7ff6214e94
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCommonDialogWithChoices.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2000-2014 JetBrains s.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.zmlx.hg4idea.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.ValidationInfo;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.util.HgUtil;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Collection;
+
+public class HgCommonDialogWithChoices extends DialogWrapper {
+
+
+ private JPanel contentPanel;
+ private JRadioButton branchOption;
+ private JRadioButton revisionOption;
+ private JRadioButton tagOption;
+ private JRadioButton bookmarkOption;
+ private JTextField revisionTxt;
+ protected JCheckBox cleanCbx;
+ private JComboBox branchSelector;
+ private JComboBox tagSelector;
+ private JComboBox bookmarkSelector;
+ protected HgRepositorySelectorComponent hgRepositorySelectorComponent;
+ protected JPanel myBranchesBorderPanel;
+
+ public HgCommonDialogWithChoices(@NotNull Project project, @NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
+ super(project, false);
+ hgRepositorySelectorComponent.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ updateRepository();
+ }
+ });
+
+ ChangeListener changeListener = new ChangeListener() {
+ public void stateChanged(ChangeEvent e) {
+ update();
+ }
+ };
+ branchOption.addChangeListener(changeListener);
+ tagOption.addChangeListener(changeListener);
+ bookmarkOption.addChangeListener(changeListener);
+ revisionOption.addChangeListener(changeListener);
+ cleanCbx.setVisible(false);
+ setRoots(repositories, selectedRepo);
+ init();
+ }
+
+ public void setRoots(Collection<HgRepository> repos,
+ @Nullable HgRepository selectedRepo) {
+ hgRepositorySelectorComponent.setRoots(repos);
+ hgRepositorySelectorComponent.setSelectedRoot(selectedRepo);
+ updateRepository();
+ }
+
+ public HgRepository getRepository() {
+ return hgRepositorySelectorComponent.getRepository();
+ }
+
+ public String getTag() {
+ return (String)tagSelector.getSelectedItem();
+ }
+
+ public boolean isTagSelected() {
+ return tagOption.isSelected();
+ }
+
+ public String getBranch() {
+ return (String)branchSelector.getSelectedItem();
+ }
+
+ public boolean isBranchSelected() {
+ return branchOption.isSelected();
+ }
+
+ public String getBookmark() {
+ return (String)bookmarkSelector.getSelectedItem();
+ }
+
+ public boolean isBookmarkSelected() {
+ return bookmarkOption.isSelected();
+ }
+
+ public String getRevision() {
+ return revisionTxt.getText();
+ }
+
+ private void update() {
+ revisionTxt.setEnabled(revisionOption.isSelected());
+ branchSelector.setEnabled(branchOption.isSelected());
+ tagSelector.setEnabled(tagOption.isSelected());
+ bookmarkSelector.setEnabled(bookmarkOption.isSelected());
+ }
+
+ private void updateRepository() {
+ HgRepository repo = hgRepositorySelectorComponent.getRepository();
+ branchSelector.setModel(new DefaultComboBoxModel(repo.getOpenedBranches().toArray()));
+ DefaultComboBoxModel tagComboBoxModel = new DefaultComboBoxModel(HgUtil.getNamesWithoutHashes(repo.getTags()).toArray());
+ tagComboBoxModel.addElement("tip"); //HgRepository does not store 'tip' tag because it is internal and not included in tags file
+ tagSelector.setModel(tagComboBoxModel);
+ bookmarkSelector.setModel(new DefaultComboBoxModel(HgUtil.getNamesWithoutHashes(repo.getBookmarks()).toArray()));
+ update();
+ }
+
+ protected JComponent createCenterPanel() {
+ return contentPanel;
+ }
+
+ @Override
+ protected String getDimensionServiceKey() {
+ return getClass().getName();
+ }
+
+ protected void createUIComponents() {
+ }
+
+ public String getTargetValue() {
+ return isBranchSelected() ? getBranch() : isBookmarkSelected() ? getBookmark() : isTagSelected() ? getTag() : getRevision();
+ }
+
+ protected ValidationInfo doValidate() {
+ String message = "You have to specify appropriate name or revision.";
+ return StringUtil.isEmptyOrSpaces(getTargetValue()) ? new ValidationInfo(message, myBranchesBorderPanel) : null;
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgMergeDialog.form b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgMergeDialog.form
deleted file mode 100644
index 5a9411c4b563..000000000000
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgMergeDialog.form
+++ /dev/null
@@ -1,139 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.zmlx.hg4idea.ui.HgMergeDialog">
- <grid id="27dc6" binding="contentPanel" 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="500" height="400"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children>
- <grid id="a0d6" 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="1" column="0" row-span="1" col-span="2" 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="Merge with"/>
- <children>
- <component id="99075" class="javax.swing.JRadioButton" binding="branchOption">
- <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>
- <selected value="true"/>
- <text value="&amp;Branch"/>
- </properties>
- </component>
- <component id="653f0" class="javax.swing.JRadioButton" binding="tagOption">
- <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;Tag"/>
- </properties>
- </component>
- <component id="cefd6" class="javax.swing.JComboBox" binding="branchSelector">
- <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>
- <properties>
- <enabled value="true"/>
- <font name="Monospaced"/>
- </properties>
- </component>
- <component id="e6ad1" class="javax.swing.JComboBox" binding="tagSelector">
- <constraints>
- <grid row="2" 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>
- <enabled value="false"/>
- <font name="Monospaced"/>
- </properties>
- </component>
- <hspacer id="2892f">
- <constraints>
- <grid row="5" 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="f1e00" class="javax.swing.JTextField" binding="revisionTxt">
- <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>
- <enabled value="false"/>
- </properties>
- </component>
- <component id="f198c" class="javax.swing.JRadioButton" binding="revisionOption">
- <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>
- <selected value="false"/>
- <text value="&amp;Revision"/>
- </properties>
- </component>
- <component id="8ad2b" class="javax.swing.JRadioButton" binding="otherHeadRadioButton" 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>
- <selected value="false"/>
- <text value="&amp;Other head:"/>
- <toolTipText value="There is exactly one other head on this branch"/>
- </properties>
- </component>
- <component id="10618" class="javax.swing.JLabel" binding="otherHeadLabel">
- <constraints>
- <grid row="0" column="1" 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=""/>
- </properties>
- </component>
- <component id="dc07f" class="javax.swing.JRadioButton" binding="bookmarkOption">
- <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="Book&amp;mark"/>
- </properties>
- </component>
- <component id="14e6b" class="javax.swing.JComboBox" binding="bookmarkSelector">
- <constraints>
- <grid row="3" 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>
- <enabled value="false"/>
- <font name="Monospaced"/>
- </properties>
- </component>
- </children>
- </grid>
- <vspacer id="fe9e6">
- <constraints>
- <grid row="2" 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>
- <nested-form id="8b57e" form-file="org/zmlx/hg4idea/ui/HgRepositorySelectorComponent.form" binding="hgRepositorySelectorComponent">
- <constraints>
- <grid row="0" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- </nested-form>
- </children>
- </grid>
- <buttonGroups>
- <group name="mergeTarget">
- <member id="f198c"/>
- <member id="99075"/>
- <member id="653f0"/>
- <member id="8ad2b"/>
- <member id="dc07f"/>
- </group>
- </buttonGroups>
-</form>
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgMergeDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgMergeDialog.java
index f41972a47cea..259fe1192c3b 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgMergeDialog.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgMergeDialog.java
@@ -12,181 +12,27 @@
// limitations under the License.
package org.zmlx.hg4idea.ui;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.ui.UIUtil;
+import com.intellij.ui.IdeBorderFactory;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.HgRevisionNumber;
-import org.zmlx.hg4idea.command.HgHeadsCommand;
-import org.zmlx.hg4idea.command.HgTagBranch;
-import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand;
-import org.zmlx.hg4idea.util.HgBranchesAndTags;
-import org.zmlx.hg4idea.util.HgUiUtil;
+import org.zmlx.hg4idea.repo.HgRepository;
-import javax.swing.*;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-public class HgMergeDialog extends DialogWrapper {
+public class HgMergeDialog extends HgCommonDialogWithChoices {
- private final Project project;
-
- private JRadioButton revisionOption;
- private JTextField revisionTxt;
- private JRadioButton branchOption;
- private JRadioButton tagOption;
- private JRadioButton bookmarkOption;
- private JComboBox branchSelector;
- private JComboBox tagSelector;
- private JComboBox bookmarkSelector;
- private JPanel contentPanel;
- private HgRepositorySelectorComponent hgRepositorySelectorComponent;
- private JRadioButton otherHeadRadioButton;
- private JLabel otherHeadLabel;
-
- private HgRevisionNumber otherHead;
- private Map<VirtualFile, Collection<HgTagBranch>> branchesForRepos;
- private Map<VirtualFile, Collection<HgTagBranch>> tagsForRepos;
- private Map<VirtualFile, Collection<HgTagBranch>> bookmarksForRepos;
-
- public HgMergeDialog(Project project,
- Collection<VirtualFile> roots,
- @Nullable VirtualFile selectedRepo, HgBranchesAndTags branchesAndTags) {
- super(project, false);
- this.project = project;
- branchesForRepos = branchesAndTags.getBranchesForRepos();
- tagsForRepos = branchesAndTags.getTagsForRepos();
- bookmarksForRepos = branchesAndTags.getBookmarksForRepos();
- setRoots(roots, selectedRepo);
+ public HgMergeDialog(@NotNull Project project,
+ @NotNull Collection<HgRepository> repositories,
+ @Nullable HgRepository selectedRepo) {
+ super(project, repositories, selectedRepo);
hgRepositorySelectorComponent.setTitle("Select repository to merge");
- hgRepositorySelectorComponent.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- updateRepository();
- }
- });
-
- ChangeListener changeListener = new ChangeListener() {
- public void stateChanged(ChangeEvent e) {
- updateOptions();
- }
- };
- branchOption.addChangeListener(changeListener);
- tagOption.addChangeListener(changeListener);
- bookmarkOption.addChangeListener(changeListener);
- revisionOption.addChangeListener(changeListener);
- otherHeadRadioButton.addChangeListener(changeListener);
+ myBranchesBorderPanel.setBorder(IdeBorderFactory.createTitledBorder("Merge with", true));
setTitle("Merge");
- init();
- }
-
- public void setRoots(Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo) {
- hgRepositorySelectorComponent.setRoots(repos);
- hgRepositorySelectorComponent.setSelectedRoot(selectedRepo);
- updateRepository();
- }
-
- public VirtualFile getRepository() {
- return hgRepositorySelectorComponent.getRepository();
- }
-
- public HgTagBranch getBranch() {
- return branchOption.isSelected() ? (HgTagBranch) branchSelector.getSelectedItem() : null;
- }
-
- public HgTagBranch getTag() {
- return tagOption.isSelected() ? (HgTagBranch) tagSelector.getSelectedItem() : null;
- }
-
- public HgTagBranch getBookmark() {
- return bookmarkOption.isSelected() ? (HgTagBranch)bookmarkSelector.getSelectedItem() : null;
- }
-
- public String getRevision() {
- return revisionOption.isSelected() ? revisionTxt.getText() : null;
- }
-
- public HgRevisionNumber getOtherHead() {
- return otherHeadRadioButton.isSelected() ? otherHead : null;
- }
-
- private void updateRepository() {
- VirtualFile repo = getRepository();
- HgUiUtil.loadContentToDialog(repo, branchesForRepos, branchSelector);
- HgUiUtil.loadContentToDialog(repo, tagsForRepos, tagSelector);
- HgUiUtil.loadContentToDialog(repo, bookmarksForRepos, bookmarkSelector);
- loadHeads(repo);
- }
-
- private void updateOptions() {
- revisionTxt.setEnabled(revisionOption.isSelected());
- branchSelector.setEnabled(branchOption.isSelected());
- tagSelector.setEnabled(tagOption.isSelected());
- bookmarkSelector.setEnabled(bookmarkOption.isSelected());
- }
-
- private void loadHeads(final VirtualFile root) {
- ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
- @Override
- public void run() {
- final List<HgRevisionNumber> heads = new HgHeadsCommand(project, root).execute();
- if (heads.size() != 2) {
- disableOtherHeadsChoice();
- return;
- }
-
- HgRevisionNumber currentParent = new HgWorkingCopyRevisionsCommand(project).identify(root).getFirst();
- for (Iterator<HgRevisionNumber> it = heads.iterator(); it.hasNext(); ) {
- final HgRevisionNumber rev = it.next();
- if (rev.getRevisionNumber().equals(currentParent.getRevisionNumber())) {
- it.remove();
- }
- }
-
- if (heads.size() == 1) {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
- @Override
- public void run() {
- otherHeadRadioButton.setVisible(true);
- otherHeadLabel.setVisible(true);
- otherHead = heads.get(0);
- otherHeadLabel.setText(" " + otherHead.asString());
- }
- });
- }
- else {
- //apparently we are not at one of the heads
- disableOtherHeadsChoice();
- }
- }
- });
- }
-
- private void disableOtherHeadsChoice() {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
- @Override
- public void run() {
- otherHeadLabel.setVisible(false);
- otherHeadRadioButton.setVisible(false);
- }
- });
- }
-
- @Nullable
- @Override
- protected JComponent createCenterPanel() {
- return contentPanel;
}
@Override
- protected String getDimensionServiceKey() {
- return getClass().getName();
+ protected String getHelpId() {
+ return "reference.mercurial.merge.dialog";
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPullDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPullDialog.java
index 5b4af4a5ba96..2729817a404e 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPullDialog.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPullDialog.java
@@ -23,8 +23,10 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorComboBox;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgRememberedInputs;
+import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.util.HgUtil;
import javax.swing.*;
@@ -40,7 +42,7 @@ public class HgPullDialog extends DialogWrapper {
private EditorComboBox myRepositoryURL;
private String myCurrentRepositoryUrl;
- public HgPullDialog(Project project) {
+ public HgPullDialog(@NotNull Project project, @NotNull Collection<HgRepository> repositories, @Nullable final HgRepository selectedRepo) {
super(project, false);
this.project = project;
hgRepositorySelector.setTitle("Select repository to pull changesets for");
@@ -53,6 +55,7 @@ public class HgPullDialog extends DialogWrapper {
setTitle("Pull");
setOKButtonText("Pull");
init();
+ setRoots(repositories, selectedRepo);
}
public void createUIComponents() {
@@ -67,7 +70,7 @@ public class HgPullDialog extends DialogWrapper {
});
}
- private void addPathsFromHgrc(VirtualFile repo) {
+ private void addPathsFromHgrc(@NotNull VirtualFile repo) {
Collection<String> paths = HgUtil.getRepositoryPaths(project, repo);
for (String path : paths) {
myRepositoryURL.prependItem(path);
@@ -80,15 +83,15 @@ public class HgPullDialog extends DialogWrapper {
}
public VirtualFile getRepository() {
- return hgRepositorySelector.getRepository();
+ return hgRepositorySelector.getRepository().getRoot();
}
public String getSource() {
return myCurrentRepositoryUrl;
}
- public void setRoots(Collection<VirtualFile> repos, @Nullable final VirtualFile selectedRepo) {
- hgRepositorySelector.setRoots(repos);
+ private void setRoots(@NotNull Collection<HgRepository> repositories, @Nullable final HgRepository selectedRepo) {
+ hgRepositorySelector.setRoots(repositories);
hgRepositorySelector.setSelectedRoot(selectedRepo);
onChangeRepository();
}
@@ -106,8 +109,8 @@ public class HgPullDialog extends DialogWrapper {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
- final VirtualFile repo = hgRepositorySelector.getRepository();
- final String defaultPath = HgUtil.getRepositoryDefaultPath(project,repo);
+ final VirtualFile repo = hgRepositorySelector.getRepository().getRoot();
+ final String defaultPath = HgUtil.getRepositoryDefaultPath(project, repo);
if (!StringUtil.isEmptyOrSpaces(defaultPath)) {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
@@ -133,5 +136,4 @@ public class HgPullDialog extends DialogWrapper {
protected String getDimensionServiceKey() {
return HgPullDialog.class.getName();
}
-
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPushDialog.form b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPushDialog.form
index a11d251812ad..ab1fd73801f5 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPushDialog.form
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPushDialog.form
@@ -3,7 +3,7 @@
<grid id="27dc6" binding="contentPanel" 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>
- <xy x="20" y="20" width="529" height="307"/>
+ <xy x="3" y="20" width="546" height="397"/>
</constraints>
<properties/>
<border type="none"/>
@@ -18,13 +18,13 @@
<children>
<vspacer id="f51de">
<constraints>
- <grid row="4" 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="4" column="0" row-span="1" col-span="1" vsize-policy="2" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
- <grid id="3b42" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="3b42" layout-manager="GridLayoutManager" row-count="3" 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="3" 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="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<minimum-size width="-1" height="100"/>
</grid>
</constraints>
@@ -34,17 +34,9 @@
</clientProperties>
<border type="etched" title="Options"/>
<children>
- <component id="e40ef" class="javax.swing.JCheckBox" binding="revisionCbx">
- <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;Revision:"/>
- </properties>
- </component>
<component id="8b024" class="javax.swing.JTextField" binding="revisionTxt">
<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">
+ <grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
@@ -55,45 +47,76 @@
</component>
<hspacer id="27a66">
<constraints>
- <grid row="3" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="2" column="1" row-span="1" col-span="2" vsize-policy="1" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
- <component id="5fcc4" class="javax.swing.JCheckBox" binding="forceCheckBox" default-binding="true">
+ <grid id="3c96d" layout-manager="GridLayoutManager" row-count="3" 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="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="1" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
- <properties>
- <text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.push.force"/>
- </properties>
- </component>
- <component id="e6341" class="javax.swing.JCheckBox" binding="branchCheckBox" default-binding="true">
+ <properties/>
+ <border type="etched" title="Branch Options"/>
+ <children>
+ <component id="1adc4" class="javax.swing.JComboBox" binding="branchComboBox">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="2" vsize-policy="4" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="e6341" class="javax.swing.JCheckBox" binding="branchCheckBox" 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="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.push.branch"/>
+ </properties>
+ </component>
+ <component id="e76b" class="javax.swing.JCheckBox" binding="newBranchCheckBox">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <enabled value="false"/>
+ <horizontalAlignment value="0"/>
+ <horizontalTextPosition value="11"/>
+ <text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.push.asNewBranch"/>
+ </properties>
+ </component>
+ <component id="131ed" class="javax.swing.JComboBox" binding="myBookmarkComboBox">
+ <constraints>
+ <grid row="2" column="1" row-span="1" col-span="2" vsize-policy="4" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <editable value="true"/>
+ </properties>
+ </component>
+ <component id="a621e" class="javax.swing.JCheckBox" binding="myBookmarkCheckBox">
+ <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 resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.push.bookmark"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+ <component id="e40ef" class="javax.swing.JCheckBox" binding="revisionCbx">
<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"/>
+ <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="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.push.branch"/>
+ <text value="&amp;Revision:"/>
</properties>
</component>
- <component id="1adc4" class="javax.swing.JComboBox" binding="branchComboBox">
- <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>
- <properties/>
- </component>
- <component id="e76b" class="javax.swing.JCheckBox" binding="newBranchCheckBox">
+ <component id="5fcc4" class="javax.swing.JCheckBox" binding="forceCheckBox" 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>
- <enabled value="false"/>
- <text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.push.asNewBranch"/>
+ <text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.push.force"/>
</properties>
</component>
- <hspacer id="af930">
- <constraints>
- <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
- </constraints>
- </hspacer>
</children>
</grid>
<nested-form id="9e17d" form-file="org/zmlx/hg4idea/ui/HgRepositorySelectorComponent.form" binding="hgRepositorySelectorComponent">
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPushDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPushDialog.java
index 7660494463ec..892bbb933a06 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPushDialog.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgPushDialog.java
@@ -13,8 +13,6 @@
package org.zmlx.hg4idea.ui;
import com.intellij.dvcs.DvcsRememberedInputs;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
@@ -24,10 +22,9 @@ import com.intellij.ui.EditorComboBox;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.HgPusher;
import org.zmlx.hg4idea.HgRememberedInputs;
import org.zmlx.hg4idea.HgVcsMessages;
-import org.zmlx.hg4idea.command.HgTagBranch;
+import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.util.HgUtil;
import javax.swing.*;
@@ -38,7 +35,6 @@ import javax.swing.event.DocumentListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
-import java.util.List;
public class HgPushDialog extends DialogWrapper {
@@ -53,9 +49,11 @@ public class HgPushDialog extends DialogWrapper {
private JComboBox branchComboBox;
private EditorComboBox myRepositoryURL;
private JCheckBox newBranchCheckBox;
+ private JComboBox myBookmarkComboBox;
+ private JCheckBox myBookmarkCheckBox;
private String myCurrentRepositoryUrl;
- public HgPushDialog(Project project, Collection<VirtualFile> repos, List<HgTagBranch> branches, @Nullable VirtualFile selectedRepo) {
+ public HgPushDialog(Project project, Collection<HgRepository> repos, @Nullable HgRepository selectedRepo) {
super(project, false);
myProject = project;
@@ -69,15 +67,22 @@ public class HgPushDialog extends DialogWrapper {
final UpdatingListener updatingListener = new UpdatingListener();
revisionCbx.addChangeListener(updatingListener);
branchCheckBox.addChangeListener(updatingListener);
+ myBookmarkCheckBox.addChangeListener(updatingListener);
revisionTxt.getDocument().addDocumentListener(updatingListener);
setTitle(HgVcsMessages.message("hg4idea.push.dialog.title"));
setOKButtonText("Push");
init();
+ setRoots(repos, selectedRepo);
+ }
+
+ private void setRoots(@NotNull Collection<HgRepository> repos,
+ @Nullable HgRepository selectedRepo) {
hgRepositorySelectorComponent.setRoots(repos);
hgRepositorySelectorComponent.setSelectedRoot(selectedRepo);
- updateBranchComboBox(branches);
+ HgRepository repo = hgRepositorySelectorComponent.getRepository();
+ updateComboBoxes(repo);
updateRepository();
}
@@ -101,10 +106,12 @@ public class HgPushDialog extends DialogWrapper {
}
}
- public VirtualFile getRepository() {
+ @NotNull
+ public HgRepository getRepository() {
return hgRepositorySelectorComponent.getRepository();
}
+ @NotNull
public String getTarget() {
return myCurrentRepositoryUrl;
}
@@ -115,8 +122,13 @@ public class HgPushDialog extends DialogWrapper {
}
@Nullable
- public HgTagBranch getBranch() {
- return branchCheckBox.isSelected() ? (HgTagBranch) branchComboBox.getSelectedItem() : null;
+ public String getBranch() {
+ return branchCheckBox.isSelected() ? (String)branchComboBox.getSelectedItem() : null;
+ }
+
+ @Nullable
+ public String getBookmarkName() {
+ return myBookmarkCheckBox.isSelected() ? (String)myBookmarkComboBox.getSelectedItem() : null;
}
public boolean isForce() {
@@ -124,8 +136,8 @@ public class HgPushDialog extends DialogWrapper {
}
public boolean isNewBranch() {
- return newBranchCheckBox.isSelected();
- }
+ return newBranchCheckBox.isSelected();
+ }
protected JComponent createCenterPanel() {
return contentPanel;
@@ -137,25 +149,21 @@ public class HgPushDialog extends DialogWrapper {
}
public void updateRepository() {
- ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
- @Override
- public void run() {
- final VirtualFile repo = hgRepositorySelectorComponent.getRepository();
- final String defaultPath = HgUtil.getRepositoryDefaultPushPath(myProject, repo);
- final List<HgTagBranch> branches = HgPusher.getBranches(myProject, repo);
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- addPathsFromHgrc(repo);
- if (defaultPath != null) {
- updateRepositoryUrlText(HgUtil.removePasswordIfNeeded(defaultPath));
- myCurrentRepositoryUrl = defaultPath;
- }
- updateBranchComboBox(branches);
- }
- }, ModalityState.stateForComponent(getRootPane()));
- }
- });
+ HgRepository repo = hgRepositorySelectorComponent.getRepository();
+ String defaultPath = HgUtil.getRepositoryDefaultPushPath(repo);
+ addPathsFromHgrc(repo.getRoot());
+ if (defaultPath != null) {
+ updateRepositoryUrlText(HgUtil.removePasswordIfNeeded(defaultPath));
+ myCurrentRepositoryUrl = defaultPath;
+ }
+ updateComboBoxes(repo);
+ }
+
+ private void updateComboBoxes(HgRepository repo) {
+ final Collection<String> branches = repo.getOpenedBranches();
+ final Collection<String> bookmarkNames = HgUtil.getNamesWithoutHashes(repo.getBookmarks());
+ branchComboBox.setModel(new DefaultComboBoxModel(branches.toArray()));
+ myBookmarkComboBox.setModel(new DefaultComboBoxModel(bookmarkNames.toArray()));
}
private void updateRepositoryUrlText(String defaultPath) {
@@ -165,15 +173,12 @@ public class HgPushDialog extends DialogWrapper {
}
}
- private void updateBranchComboBox(@NotNull List<HgTagBranch> branches) {
- branchComboBox.setModel(new DefaultComboBoxModel(branches.toArray()));
- }
-
private void update() {
setOKActionEnabled(validateOptions());
revisionTxt.setEnabled(revisionCbx.isSelected());
branchComboBox.setEnabled(branchCheckBox.isSelected());
newBranchCheckBox.setEnabled(branchCheckBox.isSelected());
+ myBookmarkComboBox.setEnabled(myBookmarkCheckBox.isSelected());
}
private boolean validateOptions() {
@@ -213,5 +218,4 @@ public class HgPushDialog extends DialogWrapper {
update();
}
}
-
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgRepositorySelectorComponent.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgRepositorySelectorComponent.java
index 89fc834de60b..edc2fb0c1dec 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgRepositorySelectorComponent.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgRepositorySelectorComponent.java
@@ -12,10 +12,10 @@
// limitations under the License.
package org.zmlx.hg4idea.ui;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.IdeBorderFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.repo.HgRepository;
import javax.swing.*;
import java.awt.event.ActionListener;
@@ -25,54 +25,31 @@ public class HgRepositorySelectorComponent {
private JComboBox repositorySelector;
private JPanel mainPanel;
- public void setRoots(Collection<VirtualFile> roots) {
+ public void setRoots(Collection<HgRepository> roots) {
DefaultComboBoxModel model = new DefaultComboBoxModel();
- for (VirtualFile repo : roots) {
- model.addElement(new RepositoryDisplay(repo));
+ for (HgRepository repo : roots) {
+ model.addElement(repo);
}
repositorySelector.setModel(model);
mainPanel.setVisible(roots.size() > 1);
}
- public void setSelectedRoot(@Nullable VirtualFile repository) {
+ public void setSelectedRoot(@Nullable HgRepository repository) {
if (repository != null) {
- repositorySelector.setSelectedItem(new RepositoryDisplay(repository));
+ repositorySelector.setSelectedItem(repository);
}
}
- public void addActionListener(ActionListener actionListener) {
+ public void addActionListener(@NotNull ActionListener actionListener) {
repositorySelector.addActionListener(actionListener);
}
- public void setTitle(String title) {
+ public void setTitle(@NotNull String title) {
mainPanel.setBorder(IdeBorderFactory.createTitledBorder(title, true));
}
- public VirtualFile getRepository() {
- return ((RepositoryDisplay) repositorySelector.getSelectedItem()).repo;
+ @NotNull
+ public HgRepository getRepository() {
+ return (HgRepository)repositorySelector.getSelectedItem();
}
-
- private class RepositoryDisplay {
- @NotNull private final VirtualFile repo;
-
- public RepositoryDisplay(@NotNull VirtualFile repo) {
- this.repo = repo;
- }
-
- @Override
- public String toString() {
- return repo.getPresentableUrl();
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj instanceof RepositoryDisplay && this.repo.equals(((RepositoryDisplay)obj).repo);
- }
-
- @Override
- public int hashCode() {
- return repo.hashCode();
- }
- }
-
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgRunConflictResolverDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgRunConflictResolverDialog.java
index ca4ab00462f6..0196bd4a16cc 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgRunConflictResolverDialog.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgRunConflictResolverDialog.java
@@ -18,10 +18,12 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgFile;
import org.zmlx.hg4idea.command.HgResolveCommand;
import org.zmlx.hg4idea.command.HgResolveStatusEnum;
+import org.zmlx.hg4idea.repo.HgRepository;
import javax.swing.*;
import java.awt.event.ActionEvent;
@@ -37,7 +39,9 @@ public class HgRunConflictResolverDialog extends DialogWrapper {
private final Project project;
- public HgRunConflictResolverDialog(Project project) {
+ public HgRunConflictResolverDialog(@NotNull Project project,
+ @NotNull Collection<HgRepository> repositories,
+ @Nullable HgRepository selectedRepo) {
super(project, false);
this.project = project;
repositorySelector.addActionListener(new ActionListener() {
@@ -47,14 +51,16 @@ public class HgRunConflictResolverDialog extends DialogWrapper {
});
setTitle("Resolve Conflicts");
init();
+ setRoots(repositories, selectedRepo);
}
- public VirtualFile getRepository() {
+ @NotNull
+ public HgRepository getRepository() {
return repositorySelector.getRepository();
}
- public void setRoots(Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo) {
- repositorySelector.setRoots(repos);
+ private void setRoots(@NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
+ repositorySelector.setRoots(repositories);
repositorySelector.setSelectedRoot(selectedRepo);
onChangeRepository();
}
@@ -64,7 +70,7 @@ public class HgRunConflictResolverDialog extends DialogWrapper {
}
private void onChangeRepository() {
- VirtualFile repo = repositorySelector.getRepository();
+ VirtualFile repo = repositorySelector.getRepository().getRoot();
HgResolveCommand command = new HgResolveCommand(project);
final ModalityState modalityState = ApplicationManager.getApplication().getModalityStateForComponent(getRootPane());
command.list(repo, new Consumer<Map<HgFile, HgResolveStatusEnum>>() {
@@ -90,5 +96,4 @@ public class HgRunConflictResolverDialog extends DialogWrapper {
}
});
}
-
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgTagDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgTagDialog.java
index 02e3e8d7a245..ba900078600a 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgTagDialog.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgTagDialog.java
@@ -16,7 +16,9 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.repo.HgRepository;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
@@ -29,7 +31,7 @@ public class HgTagDialog extends DialogWrapper {
private JTextField tagTxt;
private HgRepositorySelectorComponent hgRepositorySelectorComponent;
- public HgTagDialog(Project project) {
+ public HgTagDialog(@NotNull Project project, @NotNull Collection<HgRepository> repos, @Nullable HgRepository selectedRepo) {
super(project, false);
hgRepositorySelectorComponent.setTitle("Select repository to tag");
DocumentListener documentListener = new DocumentListener() {
@@ -50,6 +52,8 @@ public class HgTagDialog extends DialogWrapper {
setTitle("Tag");
init();
+
+ setRoots(repos, selectedRepo);
}
public String getTagName() {
@@ -57,10 +61,10 @@ public class HgTagDialog extends DialogWrapper {
}
public VirtualFile getRepository() {
- return hgRepositorySelectorComponent.getRepository();
+ return hgRepositorySelectorComponent.getRepository().getRoot();
}
- public void setRoots(Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo) {
+ private void setRoots(@NotNull Collection<HgRepository> repos, @Nullable HgRepository selectedRepo) {
hgRepositorySelectorComponent.setRoots(repos);
hgRepositorySelectorComponent.setSelectedRoot(selectedRepo);
update();
@@ -77,5 +81,4 @@ public class HgTagDialog extends DialogWrapper {
private boolean validateOptions() {
return !StringUtil.isEmptyOrSpaces(tagTxt.getText());
}
-
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateToDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateToDialog.java
index d6638dde80b4..c0b66075841b 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateToDialog.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateToDialog.java
@@ -13,141 +13,30 @@
package org.zmlx.hg4idea.ui;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.IdeBorderFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.command.HgTagBranch;
-import org.zmlx.hg4idea.util.HgBranchesAndTags;
-import org.zmlx.hg4idea.util.HgUiUtil;
+import org.zmlx.hg4idea.repo.HgRepository;
-import javax.swing.*;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.util.Collection;
-import java.util.Map;
-public class HgUpdateToDialog extends DialogWrapper {
+public class HgUpdateToDialog extends HgCommonDialogWithChoices {
- private final Project project;
-
- private JPanel contentPanel;
- private JRadioButton branchOption;
- private JRadioButton revisionOption;
- private JRadioButton tagOption;
- private JRadioButton bookmarkOption;
- private JTextField revisionTxt;
- private JCheckBox cleanCbx;
- private JComboBox branchSelector;
- private JComboBox tagSelector;
- private JComboBox bookmarkSelector;
- private HgRepositorySelectorComponent hgRepositorySelectorComponent;
- @NotNull private Map<VirtualFile, Collection<HgTagBranch>> branchesForRepos;
- @NotNull private Map<VirtualFile, Collection<HgTagBranch>> tagsForRepos;
- @NotNull private Map<VirtualFile, Collection<HgTagBranch>> bookmarksForRepos;
-
- public HgUpdateToDialog(Project project) {
- super(project, false);
- this.project = project;
+ public HgUpdateToDialog(Project project, @NotNull Collection<HgRepository> repos, @Nullable HgRepository selectedRepo) {
+ super(project, repos, selectedRepo);
+ myBranchesBorderPanel.setBorder(IdeBorderFactory.createTitledBorder("Switch to", true));
hgRepositorySelectorComponent.setTitle("Select repository to switch");
- hgRepositorySelectorComponent.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- updateRepository();
- }
- });
-
- ChangeListener changeListener = new ChangeListener() {
- public void stateChanged(ChangeEvent e) {
- update();
- }
- };
- branchOption.addChangeListener(changeListener);
- tagOption.addChangeListener(changeListener);
- bookmarkOption.addChangeListener(changeListener);
- revisionOption.addChangeListener(changeListener);
-
- setTitle("Switch working directory");
- init();
- }
-
- public void setRoots(Collection<VirtualFile> repos,
- @Nullable VirtualFile selectedRepo, HgBranchesAndTags branchesAndTags) {
- hgRepositorySelectorComponent.setRoots(repos);
- branchesForRepos = branchesAndTags.getBranchesForRepos();
- tagsForRepos = branchesAndTags.getTagsForRepos();
- bookmarksForRepos = branchesAndTags.getBookmarksForRepos();
- hgRepositorySelectorComponent.setSelectedRoot(selectedRepo);
- updateRepository();
- }
-
- public VirtualFile getRepository() {
- return hgRepositorySelectorComponent.getRepository();
- }
-
- public HgTagBranch getTag() {
- return (HgTagBranch) tagSelector.getSelectedItem();
- }
-
- public boolean isTagSelected() {
- return tagOption.isSelected();
- }
-
- public HgTagBranch getBranch() {
- return (HgTagBranch) branchSelector.getSelectedItem();
- }
-
- public boolean isBranchSelected() {
- return branchOption.isSelected();
- }
-
- public HgTagBranch getBookmark() {
- return (HgTagBranch)bookmarkSelector.getSelectedItem();
- }
-
- public boolean isBookmarkSelected() {
- return bookmarkOption.isSelected();
- }
-
- public String getRevision() {
- return revisionTxt.getText();
- }
-
- public boolean isRevisionSelected() {
- return revisionOption.isSelected();
+ setTitle("Switch Working Directory");
+ cleanCbx.setVisible(true);
+ cleanCbx.setEnabled(true);
}
public boolean isRemoveLocalChanges() {
return cleanCbx.isSelected();
}
- private void update() {
- revisionTxt.setEnabled(revisionOption.isSelected());
- branchSelector.setEnabled(branchOption.isSelected());
- tagSelector.setEnabled(tagOption.isSelected());
- bookmarkSelector.setEnabled(bookmarkOption.isSelected());
- }
-
- private void updateRepository() {
- VirtualFile repo = hgRepositorySelectorComponent.getRepository();
- HgUiUtil.loadContentToDialog(repo, branchesForRepos, branchSelector);
- HgUiUtil.loadContentToDialog(repo, tagsForRepos, tagSelector);
- HgUiUtil.loadContentToDialog(repo, bookmarksForRepos, bookmarkSelector);
- update();
- }
-
- protected JComponent createCenterPanel() {
- return contentPanel;
- }
-
@Override
protected String getHelpId() {
return "reference.mercurial.switch.working.directory";
}
-
- @Override
- protected String getDimensionServiceKey() {
- return getClass().getName();
- }
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgBranchesAndTags.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgBranchesAndTags.java
deleted file mode 100644
index 08d71414594b..000000000000
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgBranchesAndTags.java
+++ /dev/null
@@ -1,62 +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 org.zmlx.hg4idea.util;
-
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.NotNull;
-import org.zmlx.hg4idea.command.HgTagBranch;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * @author Nadya Zabrodina
- */
-
-public class HgBranchesAndTags {
-
- @NotNull private final Map<VirtualFile, Collection<HgTagBranch>> branchesForRepos = ContainerUtil.newHashMap();
- @NotNull private final Map<VirtualFile, Collection<HgTagBranch>> tagsForRepos = ContainerUtil.newHashMap();
- @NotNull private final Map<VirtualFile, Collection<HgTagBranch>> bookmarks = ContainerUtil.newHashMap();
-
- @NotNull
- public Map<VirtualFile, Collection<HgTagBranch>> getBranchesForRepos() {
- return branchesForRepos;
- }
-
- public void addBranches(@NotNull VirtualFile repo, @NotNull Collection<HgTagBranch> branches) {
- branchesForRepos.put(repo, branches);
- }
-
- @NotNull
- public Map<VirtualFile, Collection<HgTagBranch>> getTagsForRepos() {
- return tagsForRepos;
- }
-
- public void addTags(@NotNull VirtualFile repo, @NotNull Collection<HgTagBranch> tags) {
- tagsForRepos.put(repo, tags);
- }
-
- @NotNull
- public Map<VirtualFile, Collection<HgTagBranch>> getBookmarksForRepos() {
- return bookmarks;
- }
-
- public void addBookmarks(@NotNull VirtualFile repo, @NotNull Collection<HgTagBranch> tags) {
- bookmarks.put(repo, tags);
- }
-} \ No newline at end of file
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUiUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUiUtil.java
deleted file mode 100644
index 6d806b309ed0..000000000000
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUiUtil.java
+++ /dev/null
@@ -1,89 +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 org.zmlx.hg4idea.util;
-
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.Task;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.Consumer;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.HgVcsMessages;
-import org.zmlx.hg4idea.action.HgCommandResultNotifier;
-import org.zmlx.hg4idea.command.HgTagBranch;
-import org.zmlx.hg4idea.command.HgTagBranchCommand;
-import org.zmlx.hg4idea.execution.HgCommandResult;
-
-import javax.swing.*;
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * @author Nadya Zabrodina
- */
-public class HgUiUtil {
-
- public static void loadBranchesInBackgroundableAndExecuteAction(@NotNull final Project project,
- @NotNull final Collection<VirtualFile> repos,
- @NotNull final Consumer<HgBranchesAndTags> successHandler) {
- final HgBranchesAndTags branchTagInfo = new HgBranchesAndTags();
- new Task.Backgroundable(project, "Collecting information...") {
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- for (final VirtualFile repo : repos) {
- HgTagBranchCommand tagBranchCommand = new HgTagBranchCommand(project, repo);
- HgCommandResult result = tagBranchCommand.collectBranches();
- if (result == null) {
- indicator.cancel();
- return;
- }
- branchTagInfo.addBranches(repo, HgTagBranchCommand.parseResult(result));
- result = tagBranchCommand.collectTags();
- if (result == null) {
- indicator.cancel();
- return;
- }
- branchTagInfo.addTags(repo, HgTagBranchCommand.parseResult(result));
-
- result = tagBranchCommand.collectBookmarks();
- if (result == null) {
- indicator.cancel();
- return;
- }
- branchTagInfo.addBookmarks(repo, HgTagBranchCommand.parseResult(result));
- }
- }
-
- @Override
- public void onCancel() {
- new HgCommandResultNotifier(project)
- .notifyError(null, "Mercurial command failed", HgVcsMessages.message("hg4idea.branches.error.description"));
- }
-
- @Override
- public void onSuccess() {
- successHandler.consume(branchTagInfo);
- }
- }.queue();
- }
-
- public static void loadContentToDialog(@Nullable VirtualFile root, @NotNull Map<VirtualFile, Collection<HgTagBranch>> contentMap,
- @NotNull JComboBox selector) {
- assert contentMap.get(root) != null : "No information about root " + root;
- selector.setModel(new DefaultComboBoxModel(contentMap.get(root).toArray()));
- }
-}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
index fd0fc503df7d..ee7f1b4f5ce4 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
@@ -40,6 +40,7 @@ import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.impl.status.StatusBarUtil;
import com.intellij.ui.GuiUtils;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -241,6 +242,21 @@ public abstract class HgUtil {
}
/**
+ * Get hg roots for paths
+ *
+ * @param filePaths the context paths
+ * @return a set of hg roots
+ */
+ @NotNull
+ public static Set<VirtualFile> hgRoots(@NotNull Project project, @NotNull Collection<FilePath> filePaths) {
+ HashSet<VirtualFile> roots = new HashSet<VirtualFile>();
+ for (FilePath path : filePaths) {
+ ContainerUtil.addIfNotNull(roots, getHgRootOrNull(project, path));
+ }
+ return roots;
+ }
+
+ /**
* Gets the Mercurial root for the given file path or null if non exists:
* the root should not only be in directory mappings, but also the .hg repository folder should exist.
* @see #getHgRootOrThrow(com.intellij.openapi.project.Project, com.intellij.openapi.vcs.FilePath)
@@ -596,6 +612,11 @@ public abstract class HgUtil {
}
@Nullable
+ public static String getRepositoryDefaultPushPath(@NotNull HgRepository repository) {
+ return repository.getRepositoryConfig().getDefaultPushPath();
+ }
+
+ @Nullable
public static String getConfig(@NotNull Project project,
@NotNull VirtualFile root,
@NotNull String section,
@@ -646,6 +667,7 @@ public abstract class HgUtil {
names.add(hash.getName());
}
}
+ Collections.sort(names);
return names;
}
diff --git a/plugins/javaFX/FxBuilderEmbedder/FxBuilderEmbedder.iml b/plugins/javaFX/FxBuilderEmbedder/FxBuilderEmbedder.iml
index 94b91b59e731..2a19b787b2f7 100644
--- a/plugins/javaFX/FxBuilderEmbedder/FxBuilderEmbedder.iml
+++ b/plugins/javaFX/FxBuilderEmbedder/FxBuilderEmbedder.iml
@@ -17,6 +17,7 @@
<SOURCES />
</library>
</orderEntry>
+ <orderEntry type="module" module-name="javaFX" />
</component>
</module>
diff --git a/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar b/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar
index 10561a4d95e1..e853e975c532 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 6748c0738622..65b15576c6a3 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
@@ -5,7 +5,10 @@ import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelContr
import com.oracle.javafx.scenebuilder.kit.editor.panel.hierarchy.treeview.HierarchyTreeViewController;
import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.InspectorPanelController;
import com.oracle.javafx.scenebuilder.kit.editor.panel.library.LibraryPanelController;
-import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument;
+import com.oracle.javafx.scenebuilder.kit.editor.selection.AbstractSelectionGroup;
+import com.oracle.javafx.scenebuilder.kit.editor.selection.ObjectSelectionGroup;
+import com.oracle.javafx.scenebuilder.kit.fxom.*;
+import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
@@ -17,6 +20,7 @@ import javafx.scene.control.SplitPane;
import javax.swing.*;
import java.net.URL;
+import java.util.*;
/**
* @author Alexander Lobas
@@ -26,8 +30,10 @@ public class SceneBuilderImpl implements SceneBuilder {
private final EditorCallback myEditorCallback;
private final JFXPanel myPanel = new JFXPanel();
private EditorController myEditorController;
- private ChangeListener<Number> myListener;
private volatile boolean mySkipChanges;
+ private ChangeListener<Number> myListener;
+ private ChangeListener<Number> mySelectionListener;
+ private final Map<String, int[][]> mySelectionState = new FixedHashMap<String, int[][]>(16);
public SceneBuilderImpl(URL url, EditorCallback editorCallback) {
myFileURL = url;
@@ -80,7 +86,6 @@ public class SceneBuilderImpl implements SceneBuilder {
Platform.runLater(new Runnable() {
@Override
public void run() {
- // TODO: restore state
loadFile();
}
});
@@ -96,13 +101,26 @@ public class SceneBuilderImpl implements SceneBuilder {
}
}
};
+ mySelectionListener = new ChangeListener<Number>() {
+ @Override
+ public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+ if (!mySkipChanges) {
+ int[][] state = getSelectionState();
+ if (state != null) {
+ mySelectionState.put(myEditorController.getFxmlText(), state);
+ }
+ }
+ }
+ };
myEditorController.getJobManager().revisionProperty().addListener(myListener);
+ myEditorController.getSelection().revisionProperty().addListener(mySelectionListener);
}
@Override
public void close() {
if (myEditorController != null) {
+ myEditorController.getSelection().revisionProperty().removeListener(mySelectionListener);
myEditorController.getJobManager().revisionProperty().removeListener(myListener);
}
}
@@ -113,6 +131,11 @@ public class SceneBuilderImpl implements SceneBuilder {
try {
String fxmlText = FXOMDocument.readContentFromURL(myFileURL);
myEditorController.setFxmlTextAndLocation(fxmlText, myFileURL);
+
+ int[][] selectionState = mySelectionState.get(fxmlText);
+ if (selectionState != null) {
+ restoreSelection(selectionState);
+ }
}
catch (Throwable e) {
myEditorCallback.handleError(e);
@@ -121,4 +144,133 @@ public class SceneBuilderImpl implements SceneBuilder {
mySkipChanges = false;
}
}
+
+ private int[][] getSelectionState() {
+ AbstractSelectionGroup group = myEditorController.getSelection().getGroup();
+ if (group instanceof ObjectSelectionGroup) {
+ Set<FXOMObject> items = ((ObjectSelectionGroup)group).getItems();
+ int[][] state = new int[items.size()][];
+ int index = 0;
+
+ for (FXOMObject item : items) {
+ IntArrayList path = new IntArrayList();
+ componentToPath(item, path);
+ state[index++] = path.toArray();
+ }
+
+ return state;
+ }
+
+ return null;
+ }
+
+ private static void componentToPath(FXOMObject component, IntArrayList path) {
+ FXOMObject parent = component.getParentObject();
+
+ if (parent != null) {
+ path.add(0, component.getParentProperty().getValues().indexOf(component));
+ componentToPath(parent, path);
+ }
+ }
+
+ private void restoreSelection(int[][] state) {
+ Collection<FXOMObject> newSelection = new ArrayList<FXOMObject>();
+ FXOMObject rootComponent = myEditorController.getFxomDocument().getFxomRoot();
+
+ for (int[] path : state) {
+ pathToComponent(newSelection, rootComponent, path, 0);
+ }
+
+ myEditorController.getSelection().select(newSelection);
+ }
+
+ private static void pathToComponent(Collection<FXOMObject> components, FXOMObject component, int[] path, int index) {
+ if (index == path.length) {
+ components.add(component);
+ }
+ else {
+ List<FXOMObject> children = Collections.emptyList();
+ Map<PropertyName, FXOMProperty> properties = ((FXOMInstance)component).getProperties();
+ for (Map.Entry<PropertyName, FXOMProperty> entry : properties.entrySet()) {
+ FXOMProperty value = entry.getValue();
+ if (value instanceof FXOMPropertyC) {
+ children = ((FXOMPropertyC)value).getValues();
+ break;
+ }
+ }
+
+ int componentIndex = path[index];
+ if (0 <= componentIndex && componentIndex < children.size()) {
+ pathToComponent(components, children.get(componentIndex), path, index + 1);
+ }
+ }
+ }
+
+ private static class FixedHashMap<K, V> extends HashMap<K, V> {
+ private final int mySize;
+ private final List<K> myKeys = new LinkedList<K>();
+
+ public FixedHashMap(int size) {
+ mySize = size;
+ }
+
+ @Override
+ public V put(K key, V value) {
+ if (!myKeys.contains(key)) {
+ if (myKeys.size() >= mySize) {
+ remove(myKeys.remove(0));
+ }
+ myKeys.add(key);
+ }
+ return super.put(key, value);
+ }
+
+ @Override
+ public V get(Object key) {
+ if (myKeys.contains(key)) {
+ int index = myKeys.indexOf(key);
+ int last = myKeys.size() - 1;
+ myKeys.set(index, myKeys.get(last));
+ myKeys.set(last, (K)key);
+ }
+ return super.get(key);
+ }
+ }
+
+ private static final int[] EMPTY_INTS = new int[0];
+
+ private static class IntArrayList {
+ private int[] myData = EMPTY_INTS;
+ private int mySize;
+
+ public void add(int index, int element) {
+ if (index > mySize || index < 0) {
+ throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + mySize);
+ }
+
+ ensureCapacity(mySize + 1);
+ System.arraycopy(myData, index, myData, index + 1, mySize - index);
+ myData[index] = element;
+ mySize++;
+ }
+
+ public void ensureCapacity(int minCapacity) {
+ int oldCapacity = myData.length;
+ if (minCapacity > oldCapacity) {
+ int[] oldData = myData;
+ int newCapacity = oldCapacity * 3 / 2 + 1;
+ if (newCapacity < minCapacity) {
+ newCapacity = minCapacity;
+ }
+ myData = new int[newCapacity];
+ System.arraycopy(oldData, 0, myData, 0, mySize);
+ }
+ }
+
+ public int[] toArray() {
+ int[] result = new int[mySize];
+ System.arraycopy(myData, 0, result, 0, mySize);
+ return result;
+ }
+ }
} \ No newline at end of file
diff --git a/plugins/javaFX/javaFX-CE/src/META-INF/plugin.xml b/plugins/javaFX/javaFX-CE/src/META-INF/plugin.xml
index e0372107d51a..6b65da2e0774 100644
--- a/plugins/javaFX/javaFX-CE/src/META-INF/plugin.xml
+++ b/plugins/javaFX/javaFX-CE/src/META-INF/plugin.xml
@@ -4,7 +4,17 @@
<version>1.0</version>
<vendor>JetBrains</vendor>
<description>
- This plugin provides JavaFX2 support.
- </description>
+ <![CDATA[
+ This plugin enables <a href="http://www.oracle.com/technetwork/java/javafx/overview/index.html">JavaFX</a> support.
+ The following features are available:
+ <ul>
+ <li>Dedicated file type.</li>
+ <li>Ability to create a project with the special file and directory structure.</li>
+ <li>JavaFX-aware coding assistance (code completion, search, navigation and refactoring in JavaFX-specific source files).</li>
+ <li>Integration with <a href="http://www.oracle.com/technetwork/java/javafx/tools/index.html">JavaFX Scene Builder</a>.</li>
+ <li>JavaFX application packaging capabilities.</li>
+ </ul>
+ ]]>
+ </description>
<xi:include href="/META-INF/common-javaFX-plugin.xml" xpointer="xpointer(/idea-plugin/*)"/>
</idea-plugin>
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/FxmlDataExternalizer.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/FxmlDataExternalizer.java
index 2de1bc61d599..384d0859f82d 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/FxmlDataExternalizer.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/FxmlDataExternalizer.java
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.javaFX;
import com.intellij.util.io.DataExternalizer;
+import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
@@ -29,7 +30,7 @@ import java.util.Set;
*/
public class FxmlDataExternalizer implements DataExternalizer<Set<String>> {
@Override
- public void save(DataOutput out, Set<String> value) throws IOException {
+ public void save(@NotNull DataOutput out, Set<String> value) throws IOException {
out.writeInt(value.size());
for (String s : value) {
out.writeUTF(s);
@@ -37,7 +38,7 @@ public class FxmlDataExternalizer implements DataExternalizer<Set<String>> {
}
@Override
- public Set<String> read(DataInput in) throws IOException {
+ public Set<String> read(@NotNull DataInput in) throws IOException {
final int size = in.readInt();
final Set<String> result = new HashSet<String>(size);
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxControllerClassIndex.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxControllerClassIndex.java
index 1caf0a037fb3..e5c39157ae8e 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxControllerClassIndex.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxControllerClassIndex.java
@@ -58,11 +58,13 @@ public class JavaFxControllerClassIndex extends ScalarIndexExtension<String> {
return myDataIndexer;
}
+ @NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return myKeyDescriptor;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return myInputFilter;
@@ -133,7 +135,7 @@ public class JavaFxControllerClassIndex extends ScalarIndexExtension<String> {
super(StdFileTypes.XML);
}
@Override
- public boolean acceptInput(final VirtualFile file) {
+ public boolean acceptInput(@NotNull final VirtualFile file) {
return JavaFxFileTypeFactory.isFxml(file);
}
}
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxCustomComponentsIndex.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxCustomComponentsIndex.java
index 50c8b8493970..2178fd89a7d9 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxCustomComponentsIndex.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxCustomComponentsIndex.java
@@ -81,11 +81,13 @@ public class JavaFxCustomComponentsIndex extends FileBasedIndexExtension<String,
return myDataIndexer;
}
+ @NotNull
@Override
public DataExternalizer<Set<String>> getValueExternalizer() {
return myDataExternalizer;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return myInputFilter;
@@ -97,6 +99,7 @@ public class JavaFxCustomComponentsIndex extends FileBasedIndexExtension<String,
return KEY;
}
+ @NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return myKeyDescriptor;
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxIdsIndex.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxIdsIndex.java
index e0fe90a2ea79..fcaaada562ca 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxIdsIndex.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFxIdsIndex.java
@@ -42,11 +42,13 @@ public class JavaFxIdsIndex extends FileBasedIndexExtension<String, Set<String>>
return myDataIndexer;
}
+ @NotNull
@Override
public DataExternalizer<Set<String>> getValueExternalizer() {
return myDataExternalizer;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return myInputFilter;
@@ -58,6 +60,7 @@ public class JavaFxIdsIndex extends FileBasedIndexExtension<String, Set<String>>
return KEY;
}
+ @NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return myKeyDescriptor;
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditorProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditorProvider.java
index de123d1ee1bb..6ea5c510ce4d 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditorProvider.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditorProvider.java
@@ -27,7 +27,7 @@ public class SceneBuilderEditorProvider implements FileEditorProvider, DumbAware
public boolean accept(@NotNull Project project, @NotNull VirtualFile file) {
return JavaFxFileTypeFactory.FXML_EXTENSION.equalsIgnoreCase(file.getExtension()) &&
SystemInfo.isJavaVersionAtLeast("1.8") &&
- Registry.is("embed.scene.builder", false);
+ Registry.is("embed.scene.builder", true);
}
@NotNull
diff --git a/plugins/junit/src/META-INF/plugin.xml b/plugins/junit/src/META-INF/plugin.xml
index d023807439dc..969fec8f58bc 100644
--- a/plugins/junit/src/META-INF/plugin.xml
+++ b/plugins/junit/src/META-INF/plugin.xml
@@ -16,7 +16,18 @@
<idea-plugin>
<name>JUnit</name>
- <description>Provides possibility to run JUnit 3.x and 4.x tests and view their results</description>
+ <description>
+ <![CDATA[
+ This plugin supports <a href="https://github.com/junit-team/junit">JUnit tests</a>.
+ The following features are available:
+ <ul>
+ <li>Ability to create JUnit 3.x or JUnit 4.x tests.</li>
+ <li>Navigation between a test and test subject.</li>
+ <li>Running tests.</li>
+ <li>Viewing test results in the dedicated Test Runner tab of the Run tool window.</li>
+ </ul>
+ ]]>
+ </description>
<version>1.0</version>
<vendor>JetBrains</vendor>
<extensions defaultExtensionNs="com.intellij">
diff --git a/plugins/maven/jps-plugin/maven-jps-plugin.iml b/plugins/maven/jps-plugin/maven-jps-plugin.iml
index 8098c4c4d4ba..f601ed39bca5 100644
--- a/plugins/maven/jps-plugin/maven-jps-plugin.iml
+++ b/plugins/maven/jps-plugin/maven-jps-plugin.iml
@@ -22,6 +22,7 @@
<SOURCES />
</library>
</orderEntry>
+ <orderEntry type="module" module-name="jps-serialization-tests" scope="TEST" />
</component>
</module>
diff --git a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java
index 8fe4348a0ade..0c4be99814c1 100644
--- a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java
+++ b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java
@@ -29,7 +29,8 @@ public interface MavenServerEmbedder extends Remote {
void customize(@Nullable MavenWorkspaceMap workspaceMap,
boolean failOnUnresolvedDependency,
@NotNull MavenServerConsole console,
- @NotNull MavenServerProgressIndicator indicator) throws RemoteException;
+ @NotNull MavenServerProgressIndicator indicator,
+ boolean alwaysUpdateSnapshots) throws RemoteException;
@NotNull
MavenServerExecutionResult resolveProject(@NotNull File file,
diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java
index 630e664c2366..7ed82b0494dc 100644
--- a/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java
+++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java
@@ -586,7 +586,8 @@ public class Maven2ServerEmbedderImpl extends MavenRemoteObject implements Maven
public void customize(@Nullable MavenWorkspaceMap workspaceMap,
boolean failOnUnresolvedDependency,
@NotNull MavenServerConsole console,
- @NotNull MavenServerProgressIndicator indicator) {
+ @NotNull MavenServerProgressIndicator indicator,
+ boolean alwaysUpdateSnapshots) {
try {
((CustomArtifactFactory)getComponent(ArtifactFactory.class)).customize();
((CustomArtifactFactory)getComponent(ProjectArtifactFactory.class)).customize();
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 ae454210c909..ded8fa37a958 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
@@ -111,6 +111,8 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven
private Date myBuildStartTime;
+ private boolean myAlwaysUpdateSnapshots;
+
public Maven3ServerEmbedderImpl(MavenServerSettings settings) throws RemoteException {
File mavenHome = settings.getMavenHome();
if (mavenHome != null) {
@@ -269,7 +271,8 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven
public void customize(@Nullable MavenWorkspaceMap workspaceMap,
boolean failOnUnresolvedDependency,
@NotNull MavenServerConsole console,
- @NotNull MavenServerProgressIndicator indicator) throws RemoteException {
+ @NotNull MavenServerProgressIndicator indicator,
+ boolean alwaysUpdateSnapshots) throws RemoteException {
try {
((CustomMaven3ArtifactFactory)getComponent(ArtifactFactory.class)).customize();
@@ -281,6 +284,8 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven
myBuildStartTime = new Date();
+ myAlwaysUpdateSnapshots = alwaysUpdateSnapshots;
+
setConsoleAndIndicator(console, new MavenServerProgressIndicatorWrapper(indicator));
}
catch (Exception e) {
@@ -349,6 +354,8 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven
final MavenExecutionRequest request =
createRequest(file, activeProfiles, Collections.<String>emptyList(), Collections.<String>emptyList());
+ request.setUpdateSnapshots(myAlwaysUpdateSnapshots);
+
final AtomicReference<MavenExecutionResult> ref = new AtomicReference<MavenExecutionResult>();
executeWithMavenSession(request, new Runnable() {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/GenerateManagedDependencyAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/GenerateManagedDependencyAction.java
index 18250c395ee5..93af00a1e1e2 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/GenerateManagedDependencyAction.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/GenerateManagedDependencyAction.java
@@ -78,10 +78,16 @@ public class GenerateManagedDependencyAction extends GenerateDomElementAction {
dependency.getGroupId().setStringValue(groupId);
dependency.getArtifactId().setStringValue(artifactId);
String typeValue = parentDependency.getType().getStringValue();
+ String classifier = parentDependency.getClassifier().getStringValue();
if (!StringUtil.isEmptyOrSpaces(typeValue)) {
dependency.getType().setStringValue(typeValue);
}
+
+ if (!StringUtil.isEmptyOrSpaces(classifier)) {
+ dependency.getClassifier().setStringValue(classifier);
+ }
+
dependency.getVersion().undefine();
}
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndex.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndex.java
index 614332fcadd4..e80920890f48 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndex.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndex.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.
@@ -666,14 +666,14 @@ public class MavenIndex {
}
private static class SetDescriptor implements DataExternalizer<Set<String>> {
- public void save(DataOutput s, Set<String> set) throws IOException {
+ public void save(@NotNull DataOutput s, Set<String> set) throws IOException {
s.writeInt(set.size());
for (String each : set) {
s.writeUTF(each);
}
}
- public Set<String> read(DataInput s) throws IOException {
+ public Set<String> read(@NotNull DataInput s) throws IOException {
int count = s.readInt();
Set<String> result = new THashSet<String>(count);
while (count-- > 0) {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java
index 4089981b1627..0019d59b3d7d 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java
@@ -1206,7 +1206,7 @@ public class MavenProjectsTree {
@NotNull ResolveContext context,
@NotNull MavenProgressIndicator process) throws MavenProcessCanceledException {
MavenEmbedderWrapper embedder = embeddersManager.getEmbedder(MavenEmbeddersManager.FOR_DEPENDENCIES_RESOLVE);
- embedder.customizeForResolve(getWorkspaceMap(), console, process);
+ embedder.customizeForResolve(getWorkspaceMap(), console, process, generalSettings.isAlwaysUpdateSnapshots());
try {
process.checkCanceled();
@@ -1321,7 +1321,7 @@ public class MavenProjectsTree {
@NotNull MavenProgressIndicator process,
@NotNull EmbedderTask task) throws MavenProcessCanceledException {
MavenEmbedderWrapper embedder = embeddersManager.getEmbedder(embedderKind);
- embedder.customizeForResolve(getWorkspaceMap(), console, process);
+ embedder.customizeForResolve(getWorkspaceMap(), console, process, false);
embedder.clearCachesFor(mavenProject.getMavenId());
try {
task.run(embedder);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java
index 12cdead53efb..33889ee9d368 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RemoveManagedFilesAction.java
@@ -20,34 +20,20 @@ import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.jetbrains.idea.maven.utils.MavenUtil;
import org.jetbrains.idea.maven.utils.actions.MavenAction;
import org.jetbrains.idea.maven.utils.actions.MavenActionUtil;
+import java.util.ArrayList;
import java.util.List;
public class RemoveManagedFilesAction extends MavenAction {
@Override
protected boolean isAvailable(AnActionEvent e) {
if (!super.isAvailable(e)) return false;
-
- List<VirtualFile> files = MavenActionUtil.getMavenProjectsFiles(e.getDataContext());
- if (files.isEmpty()) return false;
-
- return files.size() == 1 || isAllFilesAreManaged(MavenActionUtil.getProjectsManager(e.getDataContext()), files);
- }
-
- private static boolean isAllFilesAreManaged(@NotNull MavenProjectsManager projectsManager, List<VirtualFile> files) {
- for (VirtualFile file : files) {
- if (!projectsManager.isManagedFile(file)) {
- return false;
- }
- }
-
- return true;
+ return MavenActionUtil.getMavenProjectsFiles(e.getDataContext()).size() > 0;
}
@Override
@@ -57,34 +43,47 @@ public class RemoveManagedFilesAction extends MavenAction {
MavenProjectsManager projectsManager = MavenActionUtil.getProjectsManager(context);
List<VirtualFile> selectedFiles = MavenActionUtil.getMavenProjectsFiles(context);
- if (selectedFiles.size() != 1) return;
-
- VirtualFile pomXml = selectedFiles.get(0);
-
- if (!projectsManager.isManagedFile(pomXml)) {
- MavenProject mavenProject = projectsManager.findProject(pomXml);
- assert mavenProject != null;
+ List<VirtualFile> removableFiles = new ArrayList<VirtualFile>();
- String aggregatorDescription = "";
-
- MavenProject aggregator = projectsManager.findAggregator(mavenProject);
-
- if (aggregator != null) {
- aggregatorDescription = " (" + aggregator.getMavenId().getDisplayString() + ')';
+ for (VirtualFile pomXml : selectedFiles) {
+ if (projectsManager.isManagedFile(pomXml)) {
+ removableFiles.add(pomXml);
}
+ else {
+ notifyUserIfNeeded(context, projectsManager, selectedFiles, pomXml);
+ }
+ }
+ projectsManager.removeManagedFiles(removableFiles);
+ }
+
+ private static void notifyUserIfNeeded(DataContext context,
+ MavenProjectsManager projectsManager,
+ List<VirtualFile> selectedFiles,
+ VirtualFile pomXml) {
+ MavenProject mavenProject = projectsManager.findProject(pomXml);
+ assert mavenProject != null;
- Notification notification = new Notification(MavenUtil.MAVEN_NOTIFICATION_GROUP, "Failed to remove project",
- "You can not remove selected project because it's " +
- "imported as a module of another project" +
- aggregatorDescription
- +". You can use Ignore action. Only root project can be removed.",
- NotificationType.ERROR);
+ MavenProject aggregator = projectsManager.findAggregator(mavenProject);
+ while (aggregator != null && !projectsManager.isManagedFile(aggregator.getFile())) {
+ aggregator = projectsManager.findAggregator(aggregator);
+ }
- notification.setImportant(true);
- notification.notify(MavenActionUtil.getProject(context));
- return;
+ if (aggregator != null && !selectedFiles.contains(aggregator.getFile())) {
+ notifyUser(context, mavenProject, aggregator);
}
+ }
- projectsManager.removeManagedFiles(selectedFiles);
+ private static void notifyUser(DataContext context, MavenProject mavenProject, MavenProject aggregator) {
+ String aggregatorDescription = " (" + aggregator.getMavenId().getDisplayString() + ')';
+ Notification notification = new Notification(MavenUtil.MAVEN_NOTIFICATION_GROUP, "Failed to remove project",
+ "You can not remove " + mavenProject.getName() + " because it's " +
+ "imported as a module of another project" +
+ aggregatorDescription
+ + ". You can use Ignore action. Only root project can be removed.",
+ NotificationType.ERROR
+ );
+
+ notification.setImportant(true);
+ notification.notify(MavenActionUtil.getProject(context));
}
-}
+} \ No newline at end of file
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java
index c5ac93cd6d7b..a0882e7c87fd 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java
@@ -49,7 +49,7 @@ public abstract class MavenEmbedderWrapper extends RemoteObjectWrapper<MavenServ
}
public void customizeForResolve(MavenConsole console, MavenProgressIndicator indicator) {
- setCustomization(console, indicator, null, false);
+ setCustomization(console, indicator, null, false, false);
perform(new Retriable<Object>() {
@Override
public Object execute() throws RemoteException {
@@ -59,8 +59,8 @@ public abstract class MavenEmbedderWrapper extends RemoteObjectWrapper<MavenServ
});
}
- public void customizeForResolve(MavenWorkspaceMap workspaceMap, MavenConsole console, MavenProgressIndicator indicator) {
- setCustomization(console, indicator, workspaceMap, false);
+ public void customizeForResolve(MavenWorkspaceMap workspaceMap, MavenConsole console, MavenProgressIndicator indicator, boolean alwaysUpdateSnapshot) {
+ setCustomization(console, indicator, workspaceMap, false, alwaysUpdateSnapshot);
perform(new Retriable<Object>() {
@Override
public Object execute() throws RemoteException {
@@ -73,7 +73,7 @@ public abstract class MavenEmbedderWrapper extends RemoteObjectWrapper<MavenServ
public void customizeForStrictResolve(MavenWorkspaceMap workspaceMap,
MavenConsole console,
MavenProgressIndicator indicator) {
- setCustomization(console, indicator, workspaceMap, true);
+ setCustomization(console, indicator, workspaceMap, true, false);
perform(new Retriable<Object>() {
@Override
public Object execute() throws RemoteException {
@@ -87,7 +87,8 @@ public abstract class MavenEmbedderWrapper extends RemoteObjectWrapper<MavenServ
getOrCreateWrappee().customize(myCustomization.workspaceMap,
myCustomization.failOnUnresolvedDependency,
myCustomization.console,
- myCustomization.indicator);
+ myCustomization.indicator,
+ myCustomization.alwaysUpdateSnapshot);
}
@NotNull
@@ -243,12 +244,14 @@ public abstract class MavenEmbedderWrapper extends RemoteObjectWrapper<MavenServ
private synchronized void setCustomization(MavenConsole console,
MavenProgressIndicator indicator,
MavenWorkspaceMap workspaceMap,
- boolean failOnUnresolvedDependency) {
+ boolean failOnUnresolvedDependency,
+ boolean alwaysUpdateSnapshot) {
resetCustomization();
myCustomization = new Customization(MavenServerManager.wrapAndExport(console),
MavenServerManager.wrapAndExport(indicator),
workspaceMap,
- failOnUnresolvedDependency);
+ failOnUnresolvedDependency,
+ alwaysUpdateSnapshot);
}
private synchronized void resetCustomization() {
@@ -276,15 +279,18 @@ public abstract class MavenEmbedderWrapper extends RemoteObjectWrapper<MavenServ
private final MavenWorkspaceMap workspaceMap;
private final boolean failOnUnresolvedDependency;
+ private final boolean alwaysUpdateSnapshot;
private Customization(MavenServerConsole console,
MavenServerProgressIndicator indicator,
MavenWorkspaceMap workspaceMap,
- boolean failOnUnresolvedDependency) {
+ boolean failOnUnresolvedDependency,
+ boolean alwaysUpdateSnapshot) {
this.console = console;
this.indicator = indicator;
this.workspaceMap = workspaceMap;
this.failOnUnresolvedDependency = failOnUnresolvedDependency;
+ this.alwaysUpdateSnapshot = alwaysUpdateSnapshot;
}
}
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenMergingUpdateQueue.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenMergingUpdateQueue.java
index cb9ec71caa7f..e988b98add51 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenMergingUpdateQueue.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenMergingUpdateQueue.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.
@@ -78,7 +78,7 @@ public class MavenMergingUpdateQueue extends MergingUpdateQueue {
try {
EditorEventMulticaster multicaster = EditorFactory.getInstance().getEventMulticaster();
- multicaster.addCaretListener(new CaretListener() {
+ multicaster.addCaretListener(new CaretAdapter() {
public void caretPositionChanged(CaretEvent e) {
MavenMergingUpdateQueue.this.restartTimer();
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/vfs/MavenPropertiesVirtualFile.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/vfs/MavenPropertiesVirtualFile.java
index 7a8ccb550b00..000b855c5ac4 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/vfs/MavenPropertiesVirtualFile.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/vfs/MavenPropertiesVirtualFile.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.
@@ -52,46 +52,57 @@ public class MavenPropertiesVirtualFile extends VirtualFile {
return builder.toString().getBytes();
}
+ @Override
@NotNull
public String getName() {
return myPath;
}
+ @Override
@NotNull
public VirtualFileSystem getFileSystem() {
return myFS;
}
+ @Override
+ @NotNull
public String getPath() {
return myPath;
}
+ @Override
public boolean isWritable() {
return false;
}
+ @Override
public boolean isDirectory() {
return false;
}
+ @Override
public boolean isValid() {
return true;
}
+ @Override
public VirtualFile getParent() {
return null;
}
+ @Override
public VirtualFile[] getChildren() {
return null;
}
+ @Override
@NotNull
public byte[] contentsToByteArray() throws IOException {
if (myContent == null) throw new IOException();
return myContent;
}
+ @Override
public long getTimeStamp() {
return -1;
}
@@ -101,17 +112,21 @@ public class MavenPropertiesVirtualFile extends VirtualFile {
return myContent.hashCode();
}
+ @Override
public long getLength() {
return myContent.length;
}
+ @Override
public void refresh(boolean asynchronous, boolean recursive, Runnable postRunnable) {
}
+ @Override
public InputStream getInputStream() throws IOException {
return VfsUtilCore.byteStreamSkippingBOM(myContent,this);
}
+ @Override
@NotNull
public OutputStream getOutputStream(Object requestor, long newModificationStamp, long newTimeStamp) throws IOException {
throw new UnsupportedOperationException();
diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml
index 337fe0c5840f..5ef7e212f02b 100644
--- a/plugins/maven/src/main/resources/META-INF/plugin.xml
+++ b/plugins/maven/src/main/resources/META-INF/plugin.xml
@@ -2,7 +2,21 @@
<id>org.jetbrains.idea.maven</id>
<name>Maven Integration</name>
- <description>Import Maven projects and execute Maven goals</description>
+ <description>
+ <![CDATA[
+ This plugin provides <a href="http://maven.apache.org/">Maven</a> support.
+ The following features are available:
+ <ul>
+ <li>Maven Projects tool window.</li>
+ <li>Dedicated module type.</li>
+ <li>Maven repositories support.</li>
+ <li>Full editing support for pom.xml file.</li>
+ <li>Possibility to import Maven projects.</li>
+ <li>Running and debugging Maven goals.</li>
+ <li>Compiling.</li>
+ </ul>
+ ]]>
+ </description>
<vendor>JetBrains</vendor>
<extensionPoints>
diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesFileType.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesFileType.java
index 6d9d3eef17a4..fb0f8d4fdaf3 100644
--- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesFileType.java
+++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesFileType.java
@@ -63,12 +63,10 @@ public class PropertiesFileType extends LanguageFileType {
@Override
public String getCharset(@NotNull VirtualFile file, final byte[] content) {
- final EncodingRegistry encodingManager = EncodingRegistry.getInstance();
- if (encodingManager != null) {
- final Charset encoding = encodingManager.getEncoding(file, true);
- if (encoding != null) return encoding.toString();
+ Charset charset = EncodingRegistry.getInstance().getDefaultCharsetForPropertiesFiles(file);
+ if (charset == null) {
+ charset = CharsetToolkit.getDefaultSystemCharset();
}
- final Charset charset = CharsetToolkit.getDefaultSystemCharset();
- return charset != null ? charset.toString() : null;
+ return charset != null ? charset.name() : null;
}
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java
index 7a48ff9000ba..f61c3b87e80b 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.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,15 +42,19 @@ public class ResourceBundleAsVirtualFile extends VirtualFile {
return myResourceBundle;
}
+ @Override
@NotNull
public VirtualFileSystem getFileSystem() {
return LocalFileSystem.getInstance();
}
+ @Override
+ @NotNull
public String getPath() {
return getName();
}
+ @Override
@NotNull
public String getName() {
return myResourceBundle.getBaseName();
@@ -71,71 +75,88 @@ public class ResourceBundleAsVirtualFile extends VirtualFile {
return myResourceBundle.hashCode();
}
+ @Override
public void rename(Object requestor, @NotNull String newName) throws IOException {
}
+ @Override
public boolean isWritable() {
return true;
}
+ @Override
public boolean isDirectory() {
return false;
}
+ @Override
public boolean isValid() {
return true;
}
+ @Override
public VirtualFile getParent() {
return myResourceBundle.getBaseDirectory();
}
+ @Override
public VirtualFile[] getChildren() {
return EMPTY_ARRAY;
}
+ @Override
public VirtualFile createChildDirectory(Object requestor, String name) throws IOException {
throw new UnsupportedOperationException();
}
+ @Override
public VirtualFile createChildData(Object requestor, @NotNull String name) throws IOException {
throw new UnsupportedOperationException();
}
+ @Override
public void delete(Object requestor) throws IOException {
//todo
}
+ @Override
public void move(Object requestor, @NotNull VirtualFile newParent) throws IOException {
//todo
}
+ @Override
public InputStream getInputStream() throws IOException {
throw new UnsupportedOperationException();
}
+ @Override
@NotNull
public OutputStream getOutputStream(Object requestor, long newModificationStamp, long newTimeStamp) throws IOException {
throw new UnsupportedOperationException();
}
+ @Override
@NotNull
public byte[] contentsToByteArray() throws IOException {
throw new UnsupportedOperationException();
}
+ @Override
public long getModificationStamp() {
return 0;
}
+ @Override
public long getTimeStamp() {
return 0;
}
+ @Override
public long getLength() {
return 0;
}
+ @Override
public void refresh(boolean asynchronous, boolean recursive, Runnable postRunnable) {
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/xml/XmlPropertiesIndex.java b/plugins/properties/src/com/intellij/lang/properties/xml/XmlPropertiesIndex.java
index 370f07fab505..de96b39705e7 100644
--- a/plugins/properties/src/com/intellij/lang/properties/xml/XmlPropertiesIndex.java
+++ b/plugins/properties/src/com/intellij/lang/properties/xml/XmlPropertiesIndex.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.lang.properties.xml;
import com.intellij.ide.highlighter.XmlFileType;
@@ -52,16 +67,19 @@ public class XmlPropertiesIndex extends FileBasedIndexExtension<XmlPropertiesInd
return this;
}
+ @NotNull
@Override
public KeyDescriptor<Key> getKeyDescriptor() {
return this;
}
+ @NotNull
@Override
public DataExternalizer<String> getValueExternalizer() {
return ENUMERATOR_STRING_DESCRIPTOR;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return this;
@@ -78,7 +96,7 @@ public class XmlPropertiesIndex extends FileBasedIndexExtension<XmlPropertiesInd
}
@Override
- public boolean acceptInput(VirtualFile file) {
+ public boolean acceptInput(@NotNull VirtualFile file) {
return true;
}
@@ -139,7 +157,7 @@ public class XmlPropertiesIndex extends FileBasedIndexExtension<XmlPropertiesInd
private final byte[] buffer = IOUtil.allocReadWriteUTFBuffer();
@Override
- public void save(DataOutput out, Key value) throws IOException {
+ public void save(@NotNull DataOutput out, Key value) throws IOException {
out.writeBoolean(value.isMarker);
if (value.key != null) {
IOUtil.writeUTFFast(buffer, out, value.key);
@@ -147,7 +165,7 @@ public class XmlPropertiesIndex extends FileBasedIndexExtension<XmlPropertiesInd
}
@Override
- public Key read(DataInput in) throws IOException {
+ public Key read(@NotNull DataInput in) throws IOException {
boolean isMarker = in.readBoolean();
return isMarker ? MARKER_KEY : new Key(IOUtil.readUTFFast(buffer, in));
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnLoadedBrachesStorage.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnLoadedBrachesStorage.java
index 8f6de1e7c749..8fe1fa52a938 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnLoadedBrachesStorage.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnLoadedBrachesStorage.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.vcs.persistent.SmallMapSerializer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.branchConfig.InfoStorage;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
@@ -99,7 +100,7 @@ public class SvnLoadedBrachesStorage {
private DataExternalizer<Map<String, Collection<SvnBranchItem>>> createExternalizer() {
return new DataExternalizer<Map<String, Collection<SvnBranchItem>>>() {
@Override
- public void save(DataOutput out, Map<String, Collection<SvnBranchItem>> value) throws IOException {
+ public void save(@NotNull DataOutput out, Map<String, Collection<SvnBranchItem>> value) throws IOException {
out.writeInt(value.size());
ArrayList<String> keys = new ArrayList<String>(value.keySet());
Collections.sort(keys);
@@ -117,7 +118,7 @@ public class SvnLoadedBrachesStorage {
}
@Override
- public Map<String, Collection<SvnBranchItem>> read(DataInput in) throws IOException {
+ public Map<String, Collection<SvnBranchItem>> read(@NotNull DataInput in) throws IOException {
final HashMap<String, Collection<SvnBranchItem>> map = new HashMap<String, Collection<SvnBranchItem>>();
int mapSize = in.readInt();
for (int i = 0; i < mapSize; i++) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SvnBranchPointsCalculator.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SvnBranchPointsCalculator.java
index 2fd8b8b6dfa8..5d7bd6d3aa61 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SvnBranchPointsCalculator.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SvnBranchPointsCalculator.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.
@@ -28,6 +28,7 @@ import com.intellij.util.containers.MultiMap;
import com.intellij.util.continuation.TaskDescriptor;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.history.CopyData;
@@ -88,7 +89,7 @@ public class SvnBranchPointsCalculator {
}
private static class BranchDataExternalizer implements DataExternalizer<TreeMap<String,BranchCopyData>> {
- public void save(DataOutput out, TreeMap<String,BranchCopyData> value) throws IOException {
+ public void save(@NotNull DataOutput out, TreeMap<String,BranchCopyData> value) throws IOException {
out.writeInt(value.size());
for (Map.Entry<String, BranchCopyData> entry : value.entrySet()) {
out.writeUTF(entry.getKey());
@@ -100,7 +101,7 @@ public class SvnBranchPointsCalculator {
}
}
- public TreeMap<String,BranchCopyData> read(DataInput in) throws IOException {
+ public TreeMap<String,BranchCopyData> read(@NotNull DataInput in) throws IOException {
final TreeMap<String,BranchCopyData> result = new TreeMap<String, BranchCopyData>();
final int num = in.readInt();
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java
index 029b9a7d208e..db609abb2b85 100644
--- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java
@@ -21,13 +21,15 @@ import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.tasks.TaskManagerTestCase;
import com.intellij.xdebugger.XDebuggerManager;
-import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XBreakpointManager;
import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
+import com.intellij.xdebugger.breakpoints.XBreakpointType;
+import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
import com.intellij.xdebugger.impl.breakpoints.XLineBreakpointImpl;
import org.intellij.plugins.xsltDebugger.XsltBreakpointType;
import java.io.File;
+import java.util.Collection;
import java.util.List;
/**
@@ -78,10 +80,12 @@ public class ContextTest extends TaskManagerTestCase {
final WorkingContextManager manager = getContextManager();
final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(getProject()).getBreakpointManager();
+ final XsltBreakpointType type = XBreakpointType.EXTENSION_POINT_NAME.findExtension(XsltBreakpointType.class);
+
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
XLineBreakpointImpl<XBreakpointProperties> breakpoint =
- (XLineBreakpointImpl<XBreakpointProperties>)breakpointManager.addLineBreakpoint(new XsltBreakpointType(), "foo", 0, null);
+ (XLineBreakpointImpl<XBreakpointProperties>)breakpointManager.addLineBreakpoint(type, "foo", 0, null);
final String name = "foo";
manager.saveContext(name, null);
@@ -89,8 +93,8 @@ public class ContextTest extends TaskManagerTestCase {
}
});
manager.loadContext("foo");
- XBreakpoint<?>[] breakpoints = breakpointManager.getAllBreakpoints();
- assertEquals(1, breakpoints.length);
+ Collection<? extends XLineBreakpoint<XBreakpointProperties>> breakpoints = breakpointManager.getBreakpoints(type);
+ assertEquals(1, breakpoints.size());
manager.clearContext();
}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
index 0c344441e967..e9de7fb33f68 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
@@ -89,15 +89,16 @@ public class JBTerminalPanel extends TerminalPanel implements FocusListener, Ter
@Override
public void actionPerformed(AnActionEvent e) {
if (e.getInputEvent() instanceof KeyEvent) {
- action.update(e);
- if (e.getPresentation().isEnabled()) {
- action.actionPerformed(e);
+ AnActionEvent event = new AnActionEvent(e.getInputEvent(), e.getDataContext(), e.getPlace(), new Presentation(), e.getActionManager(), e.getModifiers());
+ action.update(event);
+ if (event.getPresentation().isEnabled()) {
+ action.actionPerformed(event);
}
else {
- terminalPanel.handleKeyEvent((KeyEvent)e.getInputEvent());
+ terminalPanel.handleKeyEvent((KeyEvent)event.getInputEvent());
}
- e.getInputEvent().consume();
+ event.getInputEvent().consume();
}
}
};
diff --git a/plugins/ui-designer-core/src/META-INF/plugin.xml b/plugins/ui-designer-core/src/META-INF/DesignerCorePlugin.xml
index 18d7453c0226..ede0d2b92f01 100644
--- a/plugins/ui-designer-core/src/META-INF/plugin.xml
+++ b/plugins/ui-designer-core/src/META-INF/DesignerCorePlugin.xml
@@ -1,12 +1,6 @@
<idea-plugin version="2">
- <name>UI Designer (Core)</name>
- <id>com.intellij.ui-designer-new</id>
- <description>
- Provides shared functionality for visual editing plugins.
- </description>
- <vendor>JetBrains</vendor>
- <resource-bundle>messages.DesignerBundle</resource-bundle>
+ <module value="com.intellij.ui-designer-new"/>
<depends>com.intellij.modules.lang</depends>
@@ -19,10 +13,6 @@
</component>
</project-components>
- <extensions defaultExtensionNs="com.intellij">
- <errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
- </extensions>
-
<extensionPoints>
<extensionPoint qualifiedName="Designer.customizations" interface="com.intellij.designer.DesignerCustomizations"/>
</extensionPoints>
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/DesignerEditor.java b/plugins/ui-designer-core/src/com/intellij/designer/DesignerEditor.java
index 7f29d4e3d865..4aee4999f707 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/DesignerEditor.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/DesignerEditor.java
@@ -73,6 +73,12 @@ public abstract class DesignerEditor extends UserDataHolderBase implements FileE
return myDesignerPanel.getPreferredFocusedComponent();
}
+ @NotNull
+ @Override
+ public String getName() {
+ return "Design";
+ }
+
@Override
public void dispose() {
myDesignerPanel.dispose();
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/DragTracker.java b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/DragTracker.java
index b506ff73f957..b2eb832319f5 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/DragTracker.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/DragTracker.java
@@ -125,23 +125,26 @@ public class DragTracker extends SelectionTracker {
myContext.setLocation(getLocation());
if (myContext.getComponents() == null) {
- List<RadComponent> components = RadComponent.getPureSelection(myArea.getSelection());
+ List<RadComponent> components = calculateContextComponents(RadComponent.getPureSelection(myArea.getSelection()));
+ myContext.setComponents(components);
- RadComponent parent = null;
for (RadComponent component : components) {
- if (parent == null) {
- parent = component.getParent();
- }
- else if (parent != component.getParent()) {
- components = Collections.emptyList();
- break;
- }
+ component.processDropOperation(myContext);
}
+ }
+ }
- myContext.setComponents(components);
- for (RadComponent component : components) {
- component.processDropOperation(myContext);
+ protected List<RadComponent> calculateContextComponents(List<RadComponent> components) {
+ RadComponent parent = null;
+ for (RadComponent component : components) {
+ if (parent == null) {
+ parent = component.getParent();
+ }
+ else if (parent != component.getParent()) {
+ components = Collections.emptyList();
+ break;
}
}
+ return components;
}
} \ No newline at end of file
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/model/MetaManager.java b/plugins/ui-designer-core/src/com/intellij/designer/model/MetaManager.java
index 0727b485d2fe..cfa76ef78ffd 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/model/MetaManager.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/model/MetaManager.java
@@ -60,19 +60,18 @@ public abstract class MetaManager extends ModelLoader {
Map<MetaModel, List<String>> modelToMorphing = new HashMap<MetaModel, List<String>>();
- for (Object element : rootElement.getChildren(META)) {
- loadModel(classLoader, (Element)element, modelToMorphing);
+ for (Element element : rootElement.getChildren(META)) {
+ loadModel(classLoader, element, modelToMorphing);
}
- for (Object element : rootElement.getChild(PALETTE).getChildren(GROUP)) {
- loadGroup((Element)element);
+ for (Element element : rootElement.getChild(PALETTE).getChildren(GROUP)) {
+ loadGroup(element);
}
Element wrapInElement = rootElement.getChild(WRAP_IN);
if (wrapInElement != null) {
- for (Object element : wrapInElement.getChildren(ITEM)) {
- Element item = (Element)element;
- myWrapModels.add(myTag2Model.get(item.getAttributeValue("tag")));
+ for (Element element : wrapInElement.getChildren(ITEM)) {
+ myWrapModels.add(myTag2Model.get(element.getAttributeValue("tag")));
}
}
@@ -210,8 +209,7 @@ public abstract class MetaManager extends ModelLoader {
protected PaletteGroup loadGroup(Element element) throws Exception {
PaletteGroup group = createPaletteGroup(element.getAttributeValue(NAME));
- for (Object child : element.getChildren(ITEM)) {
- Element itemElement = (Element)child;
+ for (Element itemElement : element.getChildren(ITEM)) {
MetaModel model = getModelByTag(itemElement.getAttributeValue(TAG));
PaletteItem paletteItem = model.getPaletteItem();
@@ -230,8 +228,8 @@ public abstract class MetaManager extends ModelLoader {
}
group.addItem(paletteItem);
- for (Object grandChild : itemElement.getChildren(ITEM)) {
- group.addItem(createVariationPaletteItem(paletteItem, model, (Element)grandChild));
+ for (Element grandChild : itemElement.getChildren(ITEM)) {
+ group.addItem(createVariationPaletteItem(paletteItem, model, grandChild));
}
}
else {
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 f2d2b9a05a02..defecc586594 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
@@ -35,7 +35,6 @@ import org.jetbrains.jps.builders.java.JavaBuilderUtil;
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
import org.jetbrains.jps.builders.logging.ProjectBuilderLogger;
import org.jetbrains.jps.incremental.*;
-import org.jetbrains.jps.incremental.instrumentation.BaseInstrumentingBuilder;
import org.jetbrains.jps.incremental.instrumentation.ClassProcessingBuilder;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
@@ -123,7 +122,7 @@ public class FormsInstrumenter extends FormsBuilder {
}
}
finally {
- context.processMessage(new ProgressMessage("Finished instrumenting forms [" + chunk.getName() + "]"));
+ context.processMessage(new ProgressMessage("Finished instrumenting forms [" + chunk.getPresentableShortName() + "]"));
}
return ExitCode.OK;
@@ -197,14 +196,14 @@ public class FormsInstrumenter extends FormsBuilder {
addBinding(compiled.getSourceFile(), formFile, instrumented);
try {
- context.processMessage(new ProgressMessage("Instrumenting forms... [" + chunk.getName() + "]"));
+ context.processMessage(new ProgressMessage("Instrumenting forms... [" + chunk.getPresentableShortName() + "]"));
final BinaryContent originalContent = compiled.getContent();
final ClassReader classReader =
new ClassReader(originalContent.getBuffer(), originalContent.getOffset(), originalContent.getLength());
- final int version = BaseInstrumentingBuilder.getClassFileVersion(classReader);
- final InstrumenterClassWriter classWriter = new InstrumenterClassWriter(BaseInstrumentingBuilder.getAsmClassWriterFlags(version), finder);
+ final int version = ClassProcessingBuilder.getClassFileVersion(classReader);
+ final InstrumenterClassWriter classWriter = new InstrumenterClassWriter(ClassProcessingBuilder.getAsmClassWriterFlags(version), finder);
final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, finder, nestedFormsLoader, false, classWriter);
final byte[] patchedBytes = codeGenerator.patchClass(classReader);
if (patchedBytes != null) {
diff --git a/plugins/ui-designer/jps-plugin/ui-designer-jps-plugin.iml b/plugins/ui-designer/jps-plugin/ui-designer-jps-plugin.iml
index f46639653871..70277d7b2991 100644
--- a/plugins/ui-designer/jps-plugin/ui-designer-jps-plugin.iml
+++ b/plugins/ui-designer/jps-plugin/ui-designer-jps-plugin.iml
@@ -16,6 +16,7 @@
<orderEntry type="module" module-name="instrumentation-util" />
<orderEntry type="module" module-name="forms-compiler" />
<orderEntry type="module" module-name="forms_rt" />
+ <orderEntry type="module" module-name="jps-serialization-tests" scope="TEST" />
</component>
</module>
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassIndex.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassIndex.java
index 18f23044ac0f..c9702518612f 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassIndex.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassIndex.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,11 +55,13 @@ public class FormClassIndex extends ScalarIndexExtension<String> {
return myDataIndexer;
}
+ @NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return myKeyDescriptor;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new DefaultFileTypeSpecificInputFilter(StdFileTypes.GUI_DESIGNER_FORM);
diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java
index 82e218ff65c1..f34f0fd67cb4 100644
--- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java
+++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java
@@ -132,21 +132,24 @@ public class XsltSymbolIndex extends FileBasedIndexExtension<String, XsltSymbolI
};
}
+ @NotNull
@Override
public DataExternalizer<Kind> getValueExternalizer() {
return new EnumDataDescriptor<Kind>(Kind.class);
}
+ @NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return new EnumeratorStringDescriptor();
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new DefaultFileTypeSpecificInputFilter(StdFileTypes.XML) {
@Override
- public boolean acceptInput(VirtualFile file) {
+ public boolean acceptInput(@NotNull VirtualFile file) {
return !(file.getFileSystem() instanceof JarFileSystem);
}
};
diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltStackFrame.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltStackFrame.java
index dfdded1e6a95..b8fc055afc9b 100644
--- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltStackFrame.java
+++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltStackFrame.java
@@ -47,7 +47,7 @@ public class XsltStackFrame extends XStackFrame {
}
@Override
- public void customizePresentation(ColoredTextContainer component) {
+ public void customizePresentation(@NotNull ColoredTextContainer component) {
if (myDebuggerSession.getCurrentState() == Debugger.State.SUSPENDED) {
try {
_customizePresentation(component);
diff --git a/python/helpers/pycharm_generator_utils/constants.py b/python/helpers/pycharm_generator_utils/constants.py
index 4ea8cf17309a..01079c47f687 100644
--- a/python/helpers/pycharm_generator_utils/constants.py
+++ b/python/helpers/pycharm_generator_utils/constants.py
@@ -6,7 +6,7 @@ import string
import time
-VERSION = "1.133"
+VERSION = "1.135"
OUT_ENCODING = 'utf-8'
diff --git a/python/helpers/pycharm_generator_utils/module_redeclarator.py b/python/helpers/pycharm_generator_utils/module_redeclarator.py
index 83778790a1c5..dcae2b5471c6 100644
--- a/python/helpers/pycharm_generator_utils/module_redeclarator.py
+++ b/python/helpers/pycharm_generator_utils/module_redeclarator.py
@@ -77,6 +77,7 @@ class ModuleRedeclarator(object):
self.footer_buf = Buf(self)
self.indent_size = indent_size
self._indent_step = " " * self.indent_size
+ self.split_modules = False
#
self.imported_modules = {"": the_builtins} # explicit module imports: {"name": module}
self.hidden_imports = {} # {'real_mod_name': 'alias'}; we alias names with "__" since we don't want them exported
@@ -115,7 +116,7 @@ class ModuleRedeclarator(object):
def flush(self):
init = None
try:
- if self.mod_filename and len(self.classes_buffs) >= 30:
+ if self.split_modules:
mod_path = self.outfile.strip(".py")
fname = build_output_name(mod_path, "__init__")
@@ -128,11 +129,9 @@ class ModuleRedeclarator(object):
fname = build_output_name(mod_path, buf.name)
dummy = fopen(fname, "w")
self.header_buf.flush(dummy)
+ self.imports_buf.flush(dummy)
buf.flush(dummy)
- data += "from "
- if version[0] >= 3:
- data += "."
- data += buf.name + " import " + buf.name + "\n"
+ data += self.create_local_import(buf.name)
dummy.close()
init.write(data)
@@ -158,6 +157,13 @@ class ModuleRedeclarator(object):
fake_builtin_init.__doc__ = object.__init__.__doc__ # this forces class's doc to be used instead
+ def create_local_import(self, name):
+ if len(name.split(".")) > 1: return ""
+ data = "from "
+ if version[0] >= 3:
+ data += "."
+ data += name + " import " + name + "\n"
+ return data
def find_imported_name(self, item):
"""
@@ -636,6 +642,11 @@ class ModuleRedeclarator(object):
else:
bases_list.append(base_name)
base_def = "(" + ", ".join(bases_list) + ")"
+
+ for base in bases_list:
+ local_import = self.create_local_import(base)
+ if local_import:
+ out(indent, local_import)
out(indent, "class ", p_name, base_def, ":",
skipped_bases and " # skipped bases: " + ", ".join(skipped_bases) or "")
out_doc_attr(out, p_class, indent + 1)
@@ -968,6 +979,7 @@ class ModuleRedeclarator(object):
ins_index = i # we could not go farther than current ins_index
break # ...and need not go fartehr than first known child
cls_list.insert(ins_index, (cls_name, get_mro(cls)))
+ self.split_modules = self.mod_filename and len(cls_list) >= 30
for item_name in [cls_item[0] for cls_item in cls_list]:
buf = ClassBuf(item_name, self)
self.classes_buffs.append(buf)
diff --git a/python/helpers/pydev/pydevd.py b/python/helpers/pydev/pydevd.py
index f7bfb322c7d5..590687dcd0f9 100644
--- a/python/helpers/pydev/pydevd.py
+++ b/python/helpers/pydev/pydevd.py
@@ -764,7 +764,7 @@ class PyDB:
del self.exception_set[exception]
self.always_exception_set.remove(exception)
except:
- pass
+ pydev_log.debug("Error while removing exception"%sys.exc_info()[0]);
update_exception_hook(self)
elif cmd_id == CMD_LOAD_SOURCE:
diff --git a/python/helpers/pydev/pydevd_breakpoints.py b/python/helpers/pydev/pydevd_breakpoints.py
index 0a6644b8cf01..beebebf4abed 100644
--- a/python/helpers/pydev/pydevd_breakpoints.py
+++ b/python/helpers/pydev/pydevd_breakpoints.py
@@ -127,6 +127,9 @@ def excepthook(exctype, value, tb):
debugger.force_post_mortem_stop += 1
pydevd_tracing.SetTrace(None) #no tracing from here
+
+ pydev_log.debug('Handling post-mortem stop on exception breakpoint %s'% exception_breakpoint.qname)
+
debugger.handle_post_mortem_stop(thread.additionalInfo, thread)
#=======================================================================================================================
diff --git a/python/helpers/pydev/pydevd_comm.py b/python/helpers/pydev/pydevd_comm.py
index 592a96900c73..376065fbae03 100644
--- a/python/helpers/pydev/pydevd_comm.py
+++ b/python/helpers/pydev/pydevd_comm.py
@@ -311,10 +311,12 @@ class ReaderThread(PyDBDaemonThread):
break
while buffer.find('\n') != -1:
command, buffer = buffer.split('\n', 1)
- pydev_log.debug('Received command: >>%s<<\n' % (command,))
+
args = command.split('\t', 2)
try:
- self.processCommand(int(args[0]), int(args[1]), args[2])
+ cmd_id = int(args[0])
+ pydev_log.debug('Received command: %s %s\n' % (ID_TO_MEANING.get(str(cmd_id), '???'), command,))
+ self.processCommand(cmd_id, int(args[1]), args[2])
except:
traceback.print_exc()
sys.stderr.write("Can't process net command: %s\n" % command)
@@ -383,7 +385,7 @@ class WriterThread(PyDBDaemonThread):
out = cmd.getOutgoing()
if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1:
- out_message = 'sending cmd: '
+ out_message = 'Sending cmd: '
out_message += ID_TO_MEANING.get(out[:3], 'UNKNOWN')
out_message += ' '
out_message += out
diff --git a/python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java b/python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java
index b0790146e6f6..ed2163afd9bd 100644
--- a/python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java
+++ b/python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java
@@ -25,9 +25,9 @@ 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.PythonSdkDetailsDialog;
+import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
import com.jetbrains.python.sdk.PyDetectedSdk;
-import com.jetbrains.python.sdk.PythonSdkType;
+import com.jetbrains.python.sdk.PythonSdkDetailsStep;
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
import org.jetbrains.annotations.Nullable;
@@ -63,14 +63,7 @@ public class PythonSdkChooserCombo extends ComboboxWithBrowseButton {
});
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
- final List<Sdk> sdks = PythonSdkType.getAllSdks();
- PythonSdkDetailsDialog dialog = new PythonSdkDetailsDialog(project, new NullableConsumer<Sdk>() {
- @Override
- public void consume(@Nullable Sdk sdk) {
- comboBox.setModel(new CollectionComboBoxModel(sdks, sdk));
- }
- });
- dialog.show();
+ showOptions(project);
notifyChanged(e);
}
});
@@ -81,6 +74,19 @@ public class PythonSdkChooserCombo extends ComboboxWithBrowseButton {
});
}
+ private void showOptions(final Project project) {
+ final PyConfigurableInterpreterList interpreterList = PyConfigurableInterpreterList.getInstance(project);
+ final Sdk[] sdks = interpreterList.getModel().getSdks();
+ PythonSdkDetailsStep.show(project, sdks, null, this, getButton().getLocationOnScreen(), new NullableConsumer<Sdk>() {
+ @Override
+ public void consume(@Nullable Sdk sdk) {
+ //noinspection unchecked
+ getComboBox().setModel(new CollectionComboBoxModel(interpreterList.getAllPythonSdks(), sdk));
+ }
+ }
+ );
+ }
+
private void notifyChanged(ActionEvent e) {
for (ActionListener changedListener : myChangedListeners) {
changedListener.actionPerformed(e);
diff --git a/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java b/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java
index 242d0087e682..42dbef84b6ce 100644
--- a/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java
+++ b/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java
@@ -16,7 +16,6 @@
package com.jetbrains.python.configuration;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.ex.EditorEx;
@@ -26,6 +25,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModel;
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil;
@@ -36,6 +36,9 @@ import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.FixedSizeButton;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.CollectionComboBoxModel;
import com.intellij.util.NullableConsumer;
@@ -61,7 +64,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
private final Project myProject;
@Nullable private final Module myModule;
private MySdkModelListener mySdkModelListener;
- private boolean myAddedSdk = false;
+ private List<Sdk> myAddedSdks = new ArrayList<Sdk>();
private PyConfigurableInterpreterList myInterpreterList;
private ProjectSdksModel myProjectSdksModel;
@@ -70,6 +73,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
private JButton myDetailsButton;
private static final String SHOW_ALL = "Show All";
private NullableConsumer<Sdk> myDetailsCallback;
+ private PythonSdkDetailsDialog myMoreDialog;
public PyActiveSdkConfigurable(@NotNull Project project) {
myModule = null;
@@ -87,7 +91,6 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
private void initContent() {
myInterpreterList = PyConfigurableInterpreterList.getInstance(myProject);
- myInterpreterList.setSdkCombo(mySdkCombo);
myProjectSdksModel = myInterpreterList.getModel();
mySdkModelListener = new MySdkModelListener(this);
@@ -98,8 +101,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
public void actionPerformed(ActionEvent e) {
final Sdk selectedSdk = (Sdk)mySdkCombo.getSelectedItem();
myPackagesPanel.updatePackages(selectedSdk != null ? new PyPackageManagementService(myProject, selectedSdk) : null);
- if (selectedSdk != null)
- myPackagesPanel.updateNotifications(selectedSdk);
+ myPackagesPanel.updateNotifications(selectedSdk);
}
});
myDetailsCallback = new NullableConsumer<Sdk>() {
@@ -110,7 +112,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
final Sdk addedSdk = SdkConfigurationUtil.setupSdk(myProjectSdksModel.getSdks(), sdk.getHomeDirectory(),
PythonSdkType.getInstance(), true,
null, null);
- myAddedSdk = true;
+ myAddedSdks.add(addedSdk);
myProjectSdksModel.addSdk(addedSdk);
myProjectSdksModel.removeSdk(sdk);
mySdkCombo.setSelectedItem(addedSdk);
@@ -127,26 +129,28 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
}
}
};
-
+ myMoreDialog = myModule == null ? new PythonSdkDetailsDialog(myProject, myDetailsCallback) :
+ new PythonSdkDetailsDialog(myModule, myDetailsCallback);
myDetailsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- PythonSdkDetailsStep
- .show(myProject, myProjectSdksModel.getSdks(),
- myModule == null ? new PythonSdkDetailsDialog(myProject, myDetailsCallback) :
- new PythonSdkDetailsDialog(myModule, myDetailsCallback), myMainPanel,
- myDetailsButton.getLocationOnScreen(), true,
+ PythonSdkDetailsStep.show(myProject, myProjectSdksModel.getSdks(),
+ myMoreDialog, myMainPanel,
+ myDetailsButton.getLocationOnScreen(),
new NullableConsumer<Sdk>() {
@Override
public void consume(Sdk sdk) {
if (sdk == null) return;
+ final PyRemovedSdkService sdkService = PyRemovedSdkService.getInstance();
+ sdkService.restoreSdk(sdk);
if (myProjectSdksModel.findSdk(sdk) == null) {
myProjectSdksModel.addSdk(sdk);
- myAddedSdk = true;
+ myAddedSdks.add(sdk);
}
updateSdkList(false);
mySdkCombo.getModel().setSelectedItem(sdk);
myPackagesPanel.updatePackages(new PyPackageManagementService(myProject, sdk));
+ myPackagesPanel.updateNotifications(sdk);
}
}
);
@@ -184,8 +188,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
final PackagesNotificationPanel notificationsArea = new PackagesNotificationPanel(myProject);
final JComponent notificationsComponent = notificationsArea.getComponent();
final Dimension preferredSize = mySdkCombo.getPreferredSize();
- notificationsComponent.setPreferredSize(new Dimension(500, preferredSize.height));
-
+ notificationsArea.hide();
myDetailsButton = new FixedSizeButton();
myDetailsButton.setIcon(PythonIcons.Python.InterpreterGear);
//noinspection SuspiciousNameCombination
@@ -211,7 +214,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
c.weightx = 0.0;
myMainPanel.add(myDetailsButton, c);
- c.insets = new Insets(2,2,2,2);
+ c.insets = new Insets(2,2,0,2);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
@@ -219,7 +222,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
c.gridx = 0;
c.gridy = 2;
- c.weighty = 0.5;
+ c.weighty = 1.;
c.gridwidth = 3;
c.gridheight = GridBagConstraints.RELATIVE;
c.fill = GridBagConstraints.BOTH;
@@ -229,7 +232,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 3;
-
+ c.weighty = 0.;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.SOUTH;
@@ -245,7 +248,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
public boolean isModified() {
final Sdk sdk = getSdk();
final Sdk selectedItem = (Sdk)mySdkCombo.getSelectedItem();
- return myAddedSdk || selectedItem instanceof PyDetectedSdk || sdk != myProjectSdksModel.findSdk(selectedItem);
+ return !myAddedSdks.isEmpty() || selectedItem instanceof PyDetectedSdk || sdk != myProjectSdksModel.findSdk(selectedItem);
}
@Nullable
@@ -260,18 +263,20 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
@Override
public void apply() throws ConfigurationException {
final Sdk item = (Sdk)mySdkCombo.getSelectedItem();
+ Sdk newSdk = item;
if (item instanceof PyDetectedSdk) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
+ VirtualFile sdkHome = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
@Override
- public void run() {
- final Sdk sdk = SdkConfigurationUtil.createAndAddSDK(item.getName(), PythonSdkType.getInstance());
- myProjectSdksModel.removeSdk(item);
- myProjectSdksModel.addSdk(sdk);
- updateSdkList(true);
- mySdkCombo.setSelectedItem(sdk);
- setSdk(sdk);
+ public VirtualFile compute() {
+ return LocalFileSystem.getInstance().refreshAndFindFileByPath(item.getName());
}
- }, ModalityState.any());
+ });
+ newSdk = SdkConfigurationUtil.setupSdk(ProjectJdkTable.getInstance().getAllJdks(), sdkHome, PythonSdkType.getInstance(), true, null, null);
+ if (newSdk != null) {
+ myProjectSdksModel.addSdk(newSdk);
+ mySdkCombo.setSelectedItem(newSdk);
+ myProjectSdksModel.apply();
+ }
}
else {
final Sdk sdk = myProjectSdksModel.findSdk(item);
@@ -280,13 +285,13 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
myProjectSdksModel.apply(null, true);
mySdkCombo.setSelectedItem(item);
}
- else if (myAddedSdk) {
- myProjectSdksModel.apply(null, true);
+ else if (!myAddedSdks.isEmpty()) {
+ myProjectSdksModel.apply();
}
}
final Sdk prevSdk = ProjectRootManager.getInstance(myProject).getProjectSdk();
- final Sdk selectedSdk = setSdk(item);
+ final Sdk selectedSdk = setSdk(newSdk);
// update string literals if different LanguageLevel was selected
if (prevSdk != null && selectedSdk != null) {
@@ -305,7 +310,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
}
private Sdk setSdk(Sdk item) {
- myAddedSdk = false;
+ myAddedSdks.clear();
final Sdk selectedSdk = myProjectSdksModel.findSdk(item);
if (myModule == null) {
final ProjectRootManager rootManager = ProjectRootManager.getInstance(myProject);
@@ -342,8 +347,12 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
@Override
public void reset() {
- myAddedSdk = false;
- myProjectSdksModel.reset(myProject);
+ if (!myAddedSdks.isEmpty()) {
+ for (Sdk sdk : myAddedSdks) {
+ myProjectSdksModel.removeSdk(sdk);
+ }
+ }
+ myAddedSdks.clear();
resetSdkList();
}
@@ -399,6 +408,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
public void disposeUIResources() {
myProjectSdksModel.removeListener(mySdkModelListener);
myInterpreterList.disposeModel();
+ Disposer.dispose(myMoreDialog.getDisposable());
}
private static class MySdkModelListener implements SdkModel.Listener {
@@ -410,7 +420,15 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
@Override
public void sdkAdded(Sdk sdk) {
+ final Object item = myConfigurable.mySdkCombo.getSelectedItem();
+
myConfigurable.resetSdkList();
+
+ if (item instanceof PyDetectedSdk) {
+ final String path = ((PyDetectedSdk)item).getHomePath();
+ if (path != null && path.equals(sdk.getHomePath()))
+ myConfigurable.mySdkCombo.setSelectedItem(sdk);
+ }
}
@Override
diff --git a/python/ide/src/com/jetbrains/python/configuration/PyConfigurableInterpreterList.java b/python/ide/src/com/jetbrains/python/configuration/PyConfigurableInterpreterList.java
index 87b9163eb824..c7176dd811f9 100644
--- a/python/ide/src/com/jetbrains/python/configuration/PyConfigurableInterpreterList.java
+++ b/python/ide/src/com/jetbrains/python/configuration/PyConfigurableInterpreterList.java
@@ -15,6 +15,8 @@
*/
package com.jetbrains.python.configuration;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
@@ -30,8 +32,10 @@ import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
import com.jetbrains.python.sdk.flavors.VirtualEnvSdkFlavor;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
/**
* Manages the SDK model shared between PythonSdkConfigurable and PyActiveSdkConfigurable.
@@ -40,16 +44,6 @@ import java.util.*;
*/
public class PyConfigurableInterpreterList {
private ProjectSdksModel myModel;
- private JComboBox mySdkCombo;
-
- public void setSdkCombo(final JComboBox sdkCombo) {
- mySdkCombo = sdkCombo;
- }
-
- public void setSelectedSdk(final Sdk selectedSdk) {
- if (mySdkCombo != null)
- mySdkCombo.setSelectedItem(selectedSdk);
- }
public static PyConfigurableInterpreterList getInstance(Project project) {
return ServiceManager.getService(project, PyConfigurableInterpreterList.class);
@@ -89,42 +83,51 @@ public class PyConfigurableInterpreterList {
final boolean isVEnv2 = PythonSdkType.isVirtualEnv(o2);
final boolean isRemote1 = PySdkUtil.isRemote(o1);
final boolean isRemote2 = PySdkUtil.isRemote(o2);
- final PythonSdkFlavor flavor1 = PythonSdkFlavor.getFlavor(o1);
- final PythonSdkFlavor flavor2 = PythonSdkFlavor.getFlavor(o2);
- final LanguageLevel level1 = flavor1 != null ? flavor1.getLanguageLevel(o1) : LanguageLevel.getDefault();
- final LanguageLevel level2 = flavor2 != null ? flavor2.getLanguageLevel(o2) : LanguageLevel.getDefault();
if (isVEnv1) {
- if (project != null && associatedWithCurrent(o1, project)) return -1;
+ if (project != null && associatedWithCurrent(o1, project)) {
+ if (associatedWithCurrent(o2, project)) return compareSdk(o1, o2);
+ return -1;
+ }
if (isVEnv2) {
- final int compare = Comparing.compare(level1, level2);
- if (compare != 0) return -compare;
- return Comparing.compare(o1.getName(), o2.getName());
+ return compareSdk(o1, o2);
}
return -1;
}
- if (isVEnv2) {
- return 1;
- }
+ if (isVEnv2) return 1;
if (isRemote1) return 1;
if (isRemote2) return -1;
+ return compareSdk(o1, o2);
+ }
+
+ private int compareSdk(final Sdk o1, final Sdk o2) {
+ final PythonSdkFlavor flavor1 = PythonSdkFlavor.getFlavor(o1);
+ final PythonSdkFlavor flavor2 = PythonSdkFlavor.getFlavor(o2);
+ final LanguageLevel level1 = flavor1 != null ? flavor1.getLanguageLevel(o1) : LanguageLevel.getDefault();
+ final LanguageLevel level2 = flavor2 != null ? flavor2.getLanguageLevel(o2) : LanguageLevel.getDefault();
final int compare = Comparing.compare(level1, level2);
if (compare != 0) return -compare;
return Comparing.compare(o1.getName(), o2.getName());
}
});
- final Collection<String> sdkHomes = new ArrayList<String>();
+ final List<String> sdkHomes = new ArrayList<String>();
sdkHomes.addAll(VirtualEnvSdkFlavor.INSTANCE.suggestHomePaths());
for (PythonSdkFlavor flavor : PythonSdkFlavor.getApplicableFlavors()) {
if (flavor instanceof VirtualEnvSdkFlavor) continue;
sdkHomes.addAll(flavor.suggestHomePaths());
}
-
+ Collections.sort(sdkHomes);
for (String sdkHome : SdkConfigurationUtil.filterExistingPaths(PythonSdkType.getInstance(), sdkHomes, getModel().getSdks())) {
result.add(new PyDetectedSdk(sdkHome));
}
+ Iterables.removeIf(result, new Predicate<Sdk>() {
+ @Override
+ public boolean apply(@Nullable Sdk input) {
+ return input != null && PyRemovedSdkService.getInstance().isRemoved(input);
+ }
+ });
return result;
}
diff --git a/python/ide/src/com/jetbrains/python/configuration/PyRemovedSdkService.java b/python/ide/src/com/jetbrains/python/configuration/PyRemovedSdkService.java
new file mode 100644
index 000000000000..f0927f7d1c81
--- /dev/null
+++ b/python/ide/src/com/jetbrains/python/configuration/PyRemovedSdkService.java
@@ -0,0 +1,66 @@
+/*
+ * 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.configuration;
+
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@State(
+ name = "PyRemovedSdkService",
+ storages = {
+ @Storage(
+ file = StoragePathMacros.APP_CONFIG + "/removedInterpreters.xml"
+ )}
+)
+public class PyRemovedSdkService implements PersistentStateComponent<PyRemovedSdkService> {
+
+ public static PyRemovedSdkService getInstance() {
+ return ServiceManager.getService(PyRemovedSdkService.class);
+ }
+
+ public Set<String> REMOVED_SDKS = new HashSet<String>();
+
+ public void removeSdk(@NotNull final Sdk sdk) {
+ REMOVED_SDKS.add(sdk.getHomePath());
+ }
+
+ public void restoreSdk(@NotNull final Sdk sdk) {
+ final String homePath = sdk.getHomePath();
+ if (REMOVED_SDKS.contains(homePath)) {
+ REMOVED_SDKS.remove(homePath);
+ }
+ }
+
+ public boolean isRemoved(@NotNull final Sdk sdk) {
+ final String homePath = sdk.getHomePath();
+ return REMOVED_SDKS.contains(homePath);
+ }
+
+ @Override
+ public PyRemovedSdkService getState() {
+ return this;
+ }
+
+ @Override
+ public void loadState(PyRemovedSdkService state) {
+ XmlSerializerUtil.copyBean(state, this);
+ }
+}
diff --git a/python/ide/src/com/jetbrains/python/configuration/PythonContentEntriesConfigurable.java b/python/ide/src/com/jetbrains/python/configuration/PythonContentEntriesConfigurable.java
index f67260b6b07d..e573aacf142a 100644
--- a/python/ide/src/com/jetbrains/python/configuration/PythonContentEntriesConfigurable.java
+++ b/python/ide/src/com/jetbrains/python/configuration/PythonContentEntriesConfigurable.java
@@ -22,9 +22,12 @@ import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.NonDefaultProjectConfigurable;
import com.intellij.openapi.options.OptionalConfigurable;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ui.configuration.PlatformContentEntriesConfigurable;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.PlatformUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
/**
* @author yole
@@ -50,6 +53,8 @@ public class PythonContentEntriesConfigurable extends ModuleAwareProjectConfigur
@NotNull
@Override
protected Configurable createModuleConfigurable(Module module) {
+ if (PlatformUtils.isPyCharmCommunity())
+ return new PlatformContentEntriesConfigurable(module, JavaSourceRootType.SOURCE);
return new PyContentEntriesModuleConfigurable(module);
}
}
diff --git a/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java b/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java
index 162ee67e08aa..68146c065a4e 100644
--- a/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java
+++ b/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java
@@ -18,11 +18,13 @@ package com.jetbrains.python.configuration;
import com.google.common.collect.Sets;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
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.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModel;
import com.intellij.openapi.projectRoots.SdkModificator;
@@ -34,7 +36,10 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
import com.intellij.openapi.ui.DialogBuilder;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Comparing;
-import com.intellij.remotesdk.RemoteCredentials;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.remote.RemoteCredentials;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.util.NullableConsumer;
@@ -43,7 +48,6 @@ import com.intellij.util.containers.FactoryMap;
import com.jetbrains.python.remote.PythonRemoteInterpreterManager;
import com.jetbrains.python.sdk.*;
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
-import icons.PythonIcons;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -72,9 +76,10 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
private boolean myShowOtherProjectVirtualenvs = true;
private final Module myModule;
private NullableConsumer<Sdk> myShowMoreCallback;
+ private SdkModel.Listener myListener;
public PythonSdkDetailsDialog(Project project, NullableConsumer<Sdk> showMoreCallback) {
- super(project);
+ super(project, true);
myModule = null;
setTitle("Project Interpreters");
@@ -86,6 +91,12 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
updateOkButton();
}
+ @Override
+ protected void dispose() {
+ myProjectSdksModel.removeListener(myListener);
+ super.dispose();
+ }
+
public PythonSdkDetailsDialog(Module module, NullableConsumer<Sdk> showMoreCallback) {
super(module.getProject());
myModule = module;
@@ -130,8 +141,7 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
}
})
.addExtraAction(new ToggleVirtualEnvFilterButton())
- .addExtraAction(new ShowPathButton())
- .addExtraAction(new GenerateSkeletonsButton());
+ .addExtraAction(new ShowPathButton());
decorator.setPreferredSize(new Dimension(600, 500));
myMainPanel = decorator.createPanel();
@@ -141,7 +151,7 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
}
private void addListeners() {
- myProjectSdksModel.addListener(new SdkModel.Listener() {
+ myListener = new SdkModel.Listener() {
@Override
public void sdkAdded(Sdk sdk) {
}
@@ -158,7 +168,8 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
@Override
public void sdkHomeSelected(Sdk sdk, String newSdkHome) {
}
- });
+ };
+ myProjectSdksModel.addListener(myListener);
mySdkList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
updateOkButton();
@@ -223,7 +234,6 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
if (!myShowOtherProjectVirtualenvs) {
VirtualEnvProjectFilter.removeNotMatching(myProject, pythonSdks);
}
- Collections.sort(pythonSdks, new PreferredSdkComparator());
//noinspection unchecked
mySdkList.setModel(new CollectionListModel<Sdk>(pythonSdks));
@@ -247,17 +257,20 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
private void addSdk(AnActionButton button) {
PythonSdkDetailsStep
- .show(myProject, myProjectSdksModel.getSdks(), this, myMainPanel, button.getPreferredPopupPoint().getScreenPoint(), false,
+ .show(myProject, myProjectSdksModel.getSdks(), null, myMainPanel, button.getPreferredPopupPoint().getScreenPoint(),
new NullableConsumer<Sdk>() {
@Override
public void consume(Sdk sdk) {
- addCreatedSdk(sdk, false);
+ addCreatedSdk(sdk, true);
}
});
}
private void addCreatedSdk(@Nullable final Sdk sdk, boolean newVirtualEnv) {
if (sdk != null) {
+ final PyRemovedSdkService sdkService = PyRemovedSdkService.getInstance();
+ sdkService.restoreSdk(sdk);
+
boolean isVirtualEnv = PythonSdkType.isVirtualEnv(sdk);
if (isVirtualEnv && !newVirtualEnv) {
AddVEnvOptionsDialog dialog = new AddVEnvOptionsDialog(myMainPanel);
@@ -366,13 +379,15 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
}
private void removeSdk() {
- final Sdk current_sdk = getSelectedSdk();
- if (current_sdk != null) {
- myProjectSdksModel.removeSdk(current_sdk);
- if (myModificators.containsKey(current_sdk)) {
- SdkModificator modificator = myModificators.get(current_sdk);
+ final Sdk currentSdk = getSelectedSdk();
+ if (currentSdk != null) {
+ final PyRemovedSdkService sdkService = PyRemovedSdkService.getInstance();
+ sdkService.removeSdk(currentSdk);
+ myProjectSdksModel.removeSdk(currentSdk);
+ if (myModificators.containsKey(currentSdk)) {
+ SdkModificator modificator = myModificators.get(currentSdk);
myModifiedModificators.remove(modificator);
- myModificators.remove(current_sdk);
+ myModificators.remove(currentSdk);
}
refreshSdkList();
mySdkListChanged = true;
@@ -420,7 +435,7 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
@Override
public boolean isEnabled() {
- return !(getSelectedSdk() instanceof PyDetectedSdk);
+ return getSelectedSdk() != null;
}
@Override
@@ -438,7 +453,17 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
component.setPreferredSize(new Dimension(600, 400));
component.setBorder(IdeBorderFactory.createBorder(SideBorder.ALL));
dialog.setCenterPanel(component);
- final Sdk sdk = getSelectedSdk();
+ Sdk sdk = getSelectedSdk();
+ if (sdk instanceof PyDetectedSdk) {
+ final String sdkName = sdk.getName();
+ VirtualFile sdkHome = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
+ @Override
+ public VirtualFile compute() {
+ return LocalFileSystem.getInstance().refreshAndFindFileByPath(sdkName);
+ }
+ });
+ sdk = SdkConfigurationUtil.setupSdk(ProjectJdkTable.getInstance().getAllJdks(), sdkHome, PythonSdkType.getInstance(), true, null, null);
+ }
editor.reload(sdk != null ? sdk.getSdkModificator(): null);
dialog.setTitle("Interpreter Paths");
@@ -446,36 +471,4 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
updateOkButton();
}
}
-
- private class GenerateSkeletonsButton extends AnActionButton implements DumbAware {
- public GenerateSkeletonsButton() {
- super("Generate skeletons for the selected interpreter", PythonIcons.Python.Skeleton);
- }
-
- @Override
- public boolean isEnabled() {
- return (getSelectedSdk() instanceof PyDetectedSdk);
- }
-
- @Override
- public void actionPerformed(AnActionEvent e) {
- final Sdk sdk = getSelectedSdk();
- if (sdk instanceof PyDetectedSdk) {
- try {
- myProjectSdksModel.apply();
- }
- catch (ConfigurationException ignored) {
- }
-
- final Sdk addedSdk = SdkConfigurationUtil.setupSdk(myProjectSdksModel.getSdks(), sdk.getHomeDirectory(),
- PythonSdkType.getInstance(), true,
- null, null);
- myProjectSdksModel.addSdk(addedSdk);
- myProjectSdksModel.removeSdk(sdk);
- refreshSdkList();
- mySdkList.setSelectedValue(addedSdk, true);
- updateOkButton();
- }
- }
- }
}
diff --git a/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java b/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java
index 8ee900ae3e75..fc639713d965 100644
--- a/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java
+++ b/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java
@@ -26,7 +26,7 @@ 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.remotesdk.RemoteSdkCredentials;
+import com.intellij.remote.RemoteSdkCredentials;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.ui.components.JBLabel;
diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java
index 02176e32c287..a667bb69f849 100644
--- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java
+++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java
@@ -89,7 +89,7 @@ public class PyJavaClassType implements PyClassLikeType {
}
@Override
- public boolean isBuiltin(TypeEvalContext context) {
+ public boolean isBuiltin() {
return false; // TODO: JDK's types could be considered built-in.
}
@@ -104,7 +104,7 @@ public class PyJavaClassType implements PyClassLikeType {
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
+ public PyType getReturnType(@NotNull TypeEvalContext context) {
if (myDefinition) {
return new PyJavaClassType(myClass, false);
}
@@ -113,6 +113,12 @@ public class PyJavaClassType implements PyClassLikeType {
@Nullable
@Override
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ return getReturnType(context);
+ }
+
+ @Nullable
+ @Override
public List<PyCallableParameter> getParameters(@NotNull TypeEvalContext context) {
return null;
}
diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java
index dbcc7e2fc8c9..6f0fd48e8742 100644
--- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java
+++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java
@@ -52,12 +52,18 @@ public class PyJavaMethodType implements PyCallableType {
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
+ public PyType getReturnType(@NotNull TypeEvalContext context) {
return PyJavaTypeProvider.asPyType(myMethod.getReturnType());
}
@Nullable
@Override
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ return getReturnType(context);
+ }
+
+ @Nullable
+ @Override
public List<PyCallableParameter> getParameters(@NotNull TypeEvalContext context) {
return null;
}
@@ -84,7 +90,7 @@ public class PyJavaMethodType implements PyCallableType {
}
@Override
- public boolean isBuiltin(TypeEvalContext context) {
+ public boolean isBuiltin() {
return false;
}
diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaPackageType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaPackageType.java
index 2948f2108abb..6f891c02c1c4 100644
--- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaPackageType.java
+++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaPackageType.java
@@ -31,7 +31,6 @@ import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
import com.jetbrains.python.psi.types.PyType;
-import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -96,7 +95,7 @@ public class PyJavaPackageType implements PyType {
}
@Override
- public boolean isBuiltin(TypeEvalContext context) {
+ public boolean isBuiltin() {
return false;
}
diff --git a/python/psi-api/src/com/jetbrains/python/PythonFileType.java b/python/psi-api/src/com/jetbrains/python/PythonFileType.java
index d940be65f732..d3d78c5ab98f 100644
--- a/python/psi-api/src/com/jetbrains/python/PythonFileType.java
+++ b/python/psi-api/src/com/jetbrains/python/PythonFileType.java
@@ -16,11 +16,15 @@
package com.jetbrains.python;
import com.intellij.lang.Language;
+import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
import icons.PythonPsiApiIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,6 +45,7 @@ import java.util.regex.Pattern;
*/
public class PythonFileType extends LanguageFileType {
private static final Pattern ENCODING_PATTERN = Pattern.compile("coding[:=]\\s*([-\\w.]+)");
+ public static final int MAX_CHARSET_ENCODING_LINE = 2;
public static PythonFileType INSTANCE = new PythonFileType();
@@ -100,14 +105,28 @@ public class PythonFileType extends LanguageFileType {
}
@Nullable
- public static String getCharsetFromEncodingDeclaration(String content) {
+ public static String getCharsetFromEncodingDeclaration(@NotNull PsiFile file) {
+ final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
+ final String content;
+ if (document != null && document.getLineCount() > MAX_CHARSET_ENCODING_LINE) {
+ final int offset = document.getLineEndOffset(MAX_CHARSET_ENCODING_LINE);
+ content = document.getText(TextRange.create(0, offset));
+ }
+ else {
+ content = file.getText();
+ }
+ return getCharsetFromEncodingDeclaration(content);
+ }
+
+ @Nullable
+ private static String getCharsetFromEncodingDeclaration(@Nullable String content) {
if (content == null || content.isEmpty()) {
return null;
}
try {
final BufferedReader reader = new BufferedReader(new StringReader(content));
try {
- for (int i = 0; i < 2; i++) {
+ for (int i = 0; i < MAX_CHARSET_ENCODING_LINE; i++) {
final String line = reader.readLine();
if (line == null) {
return null;
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 23a5ef7870b7..a31197ec60c1 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/Callable.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/Callable.java
@@ -20,6 +20,8 @@ import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Map;
+
/**
* Something that can be called, passed parameters to, and return something back.
@@ -34,10 +36,24 @@ public interface Callable extends PyTypedElement, PyQualifiedNameOwner {
PyParameterList getParameterList();
/**
- * @return the type of returned value.
+ * Returns the return type of the callable independent of a call site.
+ */
+ @Nullable
+ PyType getReturnType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key);
+
+ /**
+ * Returns the type of the call to the callable.
+ */
+ @Nullable
+ PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression 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
+ * mapping.
*/
@Nullable
- PyType getReturnType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite);
+ PyType getCallType(@Nullable PyExpression receiver, @NotNull Map<PyExpression, PyNamedParameter> parameters,
+ @NotNull TypeEvalContext context);
/**
* @return a methods returns itself, non-method callables return null.
diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyArgumentList.java b/python/psi-api/src/com/jetbrains/python/psi/PyArgumentList.java
index 5ba21bf90556..f89f25fdf2d2 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PyArgumentList.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyArgumentList.java
@@ -20,6 +20,8 @@ import com.jetbrains.python.psi.resolve.PyResolveContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Collection;
+
/**
* Represents an argument list of a function call.
*
@@ -27,6 +29,12 @@ import org.jetbrains.annotations.Nullable;
*/
public interface PyArgumentList extends PyElement {
+ /**
+ * @return all argument list param expressions (keyword argument or nameless)
+ */
+ @NotNull
+ Collection<PyExpression> getArgumentExpressions();
+
@NotNull
PyExpression[] getArguments();
diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyClass.java b/python/psi-api/src/com/jetbrains/python/psi/PyClass.java
index 657a54f78299..a988714c144a 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PyClass.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyClass.java
@@ -32,6 +32,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
+import java.util.Map;
/**
* Represents a class declaration in source.
@@ -113,6 +114,13 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine
PyFunction[] getMethods();
/**
+ * Get class properties.
+ * @return Map [property_name] = [{@link com.jetbrains.python.psi.Property}]
+ */
+ @NotNull
+ Map<String, Property> getProperties();
+
+ /**
* Finds a method with given name.
* @param name what to look for
* @param inherited true: search in superclasses; false: only look for methods defined in this class.
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 ff188f56c262..5707005026cb 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
@@ -39,7 +39,10 @@ public interface PyTypeProvider {
PyType getParameterType(@NotNull PyNamedParameter param, @NotNull PyFunction func, @NotNull TypeEvalContext context);
@Nullable
- PyType getReturnType(@NotNull PyFunction function, @Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context);
+ PyType getReturnType(@NotNull Callable callable, @NotNull TypeEvalContext context);
+
+ @Nullable
+ PyType getCallType(@NotNull PyFunction function, @Nullable PyQualifiedExpression 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 43261ddba84e..66fb827babe4 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
@@ -34,14 +34,19 @@ public interface PyCallableType extends PyType {
boolean isCallable();
/**
- * Returns the type which is the result of calling an instance of this type.
+ * Returns the return type of a function independent of a call site.
*
- * @return the call result type or null if invalid.
+ * For example, it may return a generic type.
* @param context
- * @param callSite
*/
@Nullable
- PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite);
+ PyType getReturnType(@NotNull TypeEvalContext context);
+
+ /**
+ * Returns the type which is the result of calling an instance of this type.
+ */
+ @Nullable
+ PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite);
/**
* Returns the list of parameter types.
diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java
index 098761020989..67ba765bbf81 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java
@@ -73,9 +73,8 @@ public interface PyType {
/**
* @return true if the type is a known built-in type.
- * @param context
*/
- boolean isBuiltin(TypeEvalContext context);
+ boolean isBuiltin();
void assertValid(String message);
}
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 6330c4a76a17..c27dc4bc04ed 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
@@ -94,8 +94,14 @@ public class PyTypeProviderBase implements PyTypeProvider {
return null;
}
+ @Nullable
+ @Override
+ public PyType getReturnType(@NotNull Callable callable, @NotNull TypeEvalContext context) {
+ return null;
+ }
+
@Override
- public PyType getReturnType(@NotNull PyFunction function, @Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context) {
+ public PyType getCallType(@NotNull PyFunction function, @Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context) {
ReturnTypeDescriptor descriptor;
synchronized (myMethodToReturnTypeMap) {
descriptor = myMethodToReturnTypeMap.get(function.getName());
diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java b/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java
index bc53ffdeceaf..f3c688bc88ae 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java
@@ -18,6 +18,7 @@ package com.jetbrains.python.psi.types;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.jetbrains.python.psi.Callable;
import com.jetbrains.python.psi.PyTypedElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,12 +42,19 @@ public class TypeEvalContext {
@Nullable private final PsiFile myOrigin;
private final Map<PyTypedElement, PyType> myEvaluated = new HashMap<PyTypedElement, PyType>();
+ private final Map<Callable, PyType> myEvaluatedReturn = new HashMap<Callable, PyType>();
private final ThreadLocal<Set<PyTypedElement>> myEvaluating = new ThreadLocal<Set<PyTypedElement>>() {
@Override
protected Set<PyTypedElement> initialValue() {
return new HashSet<PyTypedElement>();
}
};
+ private final ThreadLocal<Set<Callable>> myEvaluatingReturn = new ThreadLocal<Set<Callable>>() {
+ @Override
+ protected Set<Callable> initialValue() {
+ return new HashSet<Callable>();
+ }
+ };
private TypeEvalContext(boolean allowDataFlow, boolean allowStubToAST, @Nullable PsiFile origin) {
myAllowDataFlow = allowDataFlow;
@@ -114,64 +122,93 @@ public class TypeEvalContext {
}
return this;
}
-
+
public void trace(String message, Object... args) {
if (myTrace != null) {
myTrace.add(myTraceIndent + String.format(message, args));
}
}
-
+
public void traceIndent() {
if (myTrace != null) {
myTraceIndent += " ";
}
}
-
+
public void traceUnindent() {
if (myTrace != null && myTraceIndent.length() >= 2) {
myTraceIndent = myTraceIndent.substring(0, myTraceIndent.length()-2);
}
}
-
+
public String printTrace() {
return StringUtil.join(myTrace, "\n");
}
-
+
public boolean tracing() {
return myTrace != null;
}
@Nullable
- public PyType getType(@NotNull PyTypedElement element) {
- synchronized (myEvaluated) {
- if (myEvaluated.containsKey(element)) {
- final PyType pyType = myEvaluated.get(element);
- if (pyType != null) {
- pyType.assertValid(element.toString());
- }
- return pyType;
- }
- }
+ public PyType getType(@NotNull final PyTypedElement element) {
final Set<PyTypedElement> evaluating = myEvaluating.get();
if (evaluating.contains(element)) {
return null;
}
evaluating.add(element);
try {
- PyType result = element.getType(this, Key.INSTANCE);
- if (result != null) {
- result.assertValid(element.toString());
+ synchronized (myEvaluated) {
+ if (myEvaluated.containsKey(element)) {
+ final PyType type = myEvaluated.get(element);
+ assertValid(type, element);
+ return type;
+ }
}
+ final PyType type = element.getType(this, Key.INSTANCE);
+ assertValid(type, element);
synchronized (myEvaluated) {
- myEvaluated.put(element, result);
+ myEvaluated.put(element, type);
}
- return result;
+ return type;
}
finally {
evaluating.remove(element);
}
}
+ @Nullable
+ public PyType getReturnType(@NotNull final Callable callable) {
+ final Set<Callable> evaluating = myEvaluatingReturn.get();
+ if (evaluating.contains(callable)) {
+ return null;
+ }
+ evaluating.add(callable);
+ try {
+ synchronized (myEvaluatedReturn) {
+ if (myEvaluatedReturn.containsKey(callable)) {
+ final PyType type = myEvaluatedReturn.get(callable);
+ assertValid(type, callable);
+ return type;
+ }
+ }
+ final PyType type = callable.getReturnType(this, Key.INSTANCE);
+ assertValid(type, callable);
+ synchronized (myEvaluatedReturn) {
+ myEvaluatedReturn.put(callable, type);
+ }
+ return type;
+ }
+ finally {
+ evaluating.remove(callable);
+ }
+ }
+
+ private static void assertValid(@Nullable PyType result, @NotNull PyTypedElement element) {
+ if (result != null) {
+ result.assertValid(element.toString());
+ }
+ }
+
public boolean maySwitchToAST(@NotNull PsiElement element) {
return myAllowStubToAST || myOrigin == element.getContainingFile();
}
diff --git a/python/resources/icons/com/jetbrains/python/skeleton.png b/python/resources/icons/com/jetbrains/python/skeleton.png
deleted file mode 100644
index b77c54ca92f8..000000000000
--- a/python/resources/icons/com/jetbrains/python/skeleton.png
+++ /dev/null
Binary files differ
diff --git a/python/resources/icons/com/jetbrains/python/skeleton@2x.png b/python/resources/icons/com/jetbrains/python/skeleton@2x.png
deleted file mode 100644
index 313b0249fffa..000000000000
--- a/python/resources/icons/com/jetbrains/python/skeleton@2x.png
+++ /dev/null
Binary files differ
diff --git a/python/resources/icons/com/jetbrains/python/templateRoot.png b/python/resources/icons/com/jetbrains/python/templateRoot.png
index a736036d6426..32d4880ec454 100644
--- a/python/resources/icons/com/jetbrains/python/templateRoot.png
+++ b/python/resources/icons/com/jetbrains/python/templateRoot.png
Binary files differ
diff --git a/python/src/META-INF/python-core.xml b/python/src/META-INF/python-core.xml
index e4029126ddb8..35a7e0b37775 100644
--- a/python/src/META-INF/python-core.xml
+++ b/python/src/META-INF/python-core.xml
@@ -372,6 +372,8 @@
serviceImplementation="com.jetbrains.python.codeInsight.PyCodeInsightSettings"/>
<applicationService serviceInterface="com.jetbrains.python.testing.PyTestFrameworkService"
serviceImplementation="com.jetbrains.python.testing.PyTestFrameworkService"/>
+ <applicationService serviceInterface="com.jetbrains.python.configuration.PyRemovedSdkService"
+ serviceImplementation="com.jetbrains.python.configuration.PyRemovedSdkService"/>
<autoImportOptionsProvider instance="com.jetbrains.python.codeInsight.imports.PyAutoImportOptions"/>
<defaultLiveTemplatesProvider implementation="com.jetbrains.python.codeInsight.liveTemplates.PyDefaultLiveTemplatesProvider"/>
diff --git a/python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java b/python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java
index 1048e53b5682..27207ab31136 100644
--- a/python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java
+++ b/python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java
@@ -67,7 +67,7 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
@Nullable
@Override
- public PyType getReturnType(@NotNull PyFunction function, @Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context) {
+ public PyType getCallType(@NotNull PyFunction function, @Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context) {
if (isInsideNumPy(function)) {
final NumPyDocString docString = NumPyDocString.forFunction(function, callSite);
if (docString != null) {
diff --git a/python/src/com/jetbrains/pyqt/PyQtTypeProvider.java b/python/src/com/jetbrains/pyqt/PyQtTypeProvider.java
index d9d030c352cd..a57a4a528e0c 100644
--- a/python/src/com/jetbrains/pyqt/PyQtTypeProvider.java
+++ b/python/src/com/jetbrains/pyqt/PyQtTypeProvider.java
@@ -15,12 +15,11 @@
*/
package com.jetbrains.pyqt;
+import com.intellij.psi.util.QualifiedName;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.Callable;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFunction;
-import com.jetbrains.python.psi.PyQualifiedExpression;
-import com.intellij.psi.util.QualifiedName;
import com.jetbrains.python.psi.stubs.PyClassNameIndex;
import com.jetbrains.python.psi.types.PyClassTypeImpl;
import com.jetbrains.python.psi.types.PyType;
@@ -37,8 +36,9 @@ public class PyQtTypeProvider extends PyTypeProviderBase {
private static final String ourQt4Signal = "pyqtSignal";
@Override
- public PyType getReturnType(@NotNull PyFunction function, @Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context) {
- if (PyNames.INIT.equals(function.getName())) {
+ public PyType getReturnType(@NotNull Callable callable, @NotNull TypeEvalContext context) {
+ if (PyNames.INIT.equals(callable.getName()) && callable instanceof PyFunction) {
+ final PyFunction function = (PyFunction)callable;
final PyClass containingClass = function.getContainingClass();
if (containingClass != null && ourQt4Signal.equals(containingClass.getName())) {
final String classQName = containingClass.getQualifiedName();
diff --git a/python/src/com/jetbrains/python/codeInsight/PyMethodNameTypedHandler.java b/python/src/com/jetbrains/python/codeInsight/PyMethodNameTypedHandler.java
index f30febe2988d..15b29c1c584a 100644
--- a/python/src/com/jetbrains/python/codeInsight/PyMethodNameTypedHandler.java
+++ b/python/src/com/jetbrains/python/codeInsight/PyMethodNameTypedHandler.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.
@@ -82,8 +82,7 @@ public class PyMethodNameTypedHandler extends TypedHandlerDelegate {
if (caretOffset == chars.length() || chars.charAt(caretOffset) != ':') {
textToType += ':';
}
- EditorModificationUtil.typeInStringAtCaretHonorBlockSelection(editor, textToType, true);
- editor.getCaretModel().moveToOffset(offset + 1 + pname.length()); // right after param name
+ EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, textToType, true, 1 + pname.length()); // right after param name
return Result.STOP;
}
}
diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java
index cc7817fdf3d2..d7b1598f39a6 100644
--- a/python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java
+++ b/python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java
@@ -131,7 +131,7 @@ public class PyDictKeyNamesCompletionContributor extends CompletionContributor {
if ("dict".equals(name)) {
final TypeEvalContext context = TypeEvalContext.userInitiated(callee.getContainingFile());
final PyType type = context.getType(dictConstructor);
- if (type != null && type.isBuiltin(context)) {
+ if (type != null && type.isBuiltin()) {
final PyArgumentList list = dictConstructor.getArgumentList();
if (list == null) return;
final PyExpression[] argumentList = list.getArguments();
diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyDictConstructorToLiteralFormIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyDictConstructorToLiteralFormIntention.java
index 322a31b6419c..8a72aa233dc5 100644
--- a/python/src/com/jetbrains/python/codeInsight/intentions/PyDictConstructorToLiteralFormIntention.java
+++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyDictConstructorToLiteralFormIntention.java
@@ -58,7 +58,7 @@ public class PyDictConstructorToLiteralFormIntention extends BaseIntentionAction
if (expression != null && expression.isCalleeText("dict")) {
final TypeEvalContext context = TypeEvalContext.codeAnalysis(file);
PyType type = context.getType(expression);
- if (type != null && type.isBuiltin(context)) {
+ if (type != null && type.isBuiltin()) {
PyExpression[] argumentList = expression.getArguments();
for (PyExpression argument : argumentList) {
if (!(argument instanceof PyKeywordArgument)) return false;
diff --git a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java
index 8783a7a16b58..39222b0fef9b 100644
--- a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java
+++ b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java
@@ -225,7 +225,7 @@ public class PyOverrideImplementUtil {
statementBody.append(PyNames.PASS);
}
else {
- if (!PyNames.INIT.equals(baseFunction.getName()) && baseFunction.getReturnType(context, null) != PyNoneType.INSTANCE) {
+ if (!PyNames.INIT.equals(baseFunction.getName()) && context.getReturnType(baseFunction) != PyNoneType.INSTANCE) {
statementBody.append("return ");
}
if (baseClass.isNewStyleClass()) {
diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java
index 9ffb86d2b090..ad1d6a24bdc1 100644
--- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java
+++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java
@@ -89,13 +89,13 @@ public class PyNamedTupleType extends PyClassTypeImpl implements PyCallableType
}
@Override
- public boolean isBuiltin(TypeEvalContext context) {
+ public boolean isBuiltin() {
return false;
}
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
if (myDefinitionLevel > 0) {
return new PyNamedTupleType(myClass, myDeclaration, myName, myFields, myDefinitionLevel-1);
}
diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java
index 9cdf4c30994a..d7678c2cd871 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 getReturnType(@NotNull PyFunction function, @Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context) {
+ public PyType getCallType(@NotNull PyFunction function, @Nullable PyQualifiedExpression 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/codeInsight/userSkeletons/PyUserSkeletonsTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsTypeProvider.java
index b900e28f93c0..6fa6529f3dfc 100644
--- a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsTypeProvider.java
+++ b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsTypeProvider.java
@@ -42,11 +42,12 @@ public class PyUserSkeletonsTypeProvider extends PyTypeProviderBase {
return null;
}
+ @Nullable
@Override
- public PyType getReturnType(@NotNull PyFunction function, @Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context) {
- final PyFunction functionSkeleton = PyUserSkeletonsUtil.getUserSkeleton(function);
- if (functionSkeleton != null) {
- return functionSkeleton.getReturnType(context, callSite);
+ public PyType getReturnType(@NotNull Callable callable, @NotNull TypeEvalContext context) {
+ final Callable callableSkeleton = PyUserSkeletonsUtil.getUserSkeleton(callable);
+ if (callableSkeleton != null) {
+ return context.getReturnType(callableSkeleton);
}
return null;
}
diff --git a/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.form b/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.form
index b6a71ee6ef38..5aacd414fb03 100644
--- a/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.form
+++ b/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.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.jetbrains.python.configuration.PyIntegratedToolsConfigurable">
- <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="9" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="myMainPanel" 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="20" y="20" width="657" height="302"/>
@@ -24,12 +24,12 @@
</component>
<vspacer id="fc19e">
<constraints>
- <grid row="8" 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="7" 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>
<grid id="728f8" binding="myErrorPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
- <grid row="7" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="6" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -52,7 +52,7 @@
<grid id="e7a5f" binding="myDocStringsPanel" layout-manager="GridLayoutManager" row-count="2" 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="3" column="0" row-span="2" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="2" column="0" row-span="2" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -87,7 +87,7 @@
<grid id="9f040" binding="myRestPanel" layout-manager="GridLayoutManager" row-count="2" 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="0" row-span="2" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="4" column="0" row-span="2" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -117,20 +117,6 @@
</component>
</children>
</grid>
- <component id="a95d2" class="javax.swing.JComboBox" binding="myTemplateLanguage">
- <constraints>
- <grid row="2" 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="36fa5" 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 value="Template language:"/>
- </properties>
- </component>
</children>
</grid>
</form>
diff --git a/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java b/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java
index 63d88c837d76..838839ffcf63 100644
--- a/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java
+++ b/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java
@@ -54,7 +54,6 @@ import com.jetbrains.python.documentation.DocStringFormat;
import com.jetbrains.python.documentation.PyDocumentationSettings;
import com.jetbrains.python.packaging.*;
import com.jetbrains.python.sdk.PythonSdkType;
-import com.jetbrains.python.templateLanguages.TemplatesService;
import com.jetbrains.python.testing.PythonTestConfigurationsModel;
import com.jetbrains.python.testing.TestRunnerService;
import com.jetbrains.python.testing.VFSTestFrameworkListener;
@@ -63,7 +62,6 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -85,9 +83,6 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable, No
private JCheckBox analyzeDoctest;
private JPanel myDocStringsPanel;
private JPanel myRestPanel;
- private JComboBox myTemplateLanguage;
- private TemplatesConfigurationsModel myTemplatesModel;
- private TemplatesService myTemplatesService;
public PyIntegratedToolsConfigurable(@NotNull Module module) {
myModule = module;
@@ -107,7 +102,6 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable, No
myDocStringsPanel.setBorder(IdeBorderFactory.createTitledBorder("Docstrings"));
myRestPanel.setBorder(IdeBorderFactory.createTitledBorder("reStructuredText"));
- myTemplatesService = TemplatesService.getInstance(module);
}
@NotNull
@@ -198,10 +192,6 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable, No
myModel = new PythonTestConfigurationsModel(configurations,
TestRunnerService.getInstance(myModule).getProjectConfiguration(), myModule);
- List<String> templateConfigurations = TemplatesService.getAllTemplateLanguages();
- myTemplatesModel = new TemplatesConfigurationsModel(templateConfigurations, myTemplatesService);
- //noinspection unchecked
- myTemplateLanguage.setModel(myTemplatesModel);
updateConfigurations();
initErrorValidation();
return myMainPanel;
@@ -231,9 +221,6 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable, No
if (!getRequirementsPath().equals(myRequirementsPathField.getText())) {
return true;
}
- if (myTemplateLanguage.getSelectedItem() != myTemplatesModel.getTemplateLanguage()) {
- return true;
- }
return false;
}
@@ -242,11 +229,6 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable, No
if (!Comparing.equal(myDocstringFormatComboBox.getSelectedItem(), myDocumentationSettings.myDocStringFormat)) {
DaemonCodeAnalyzer.getInstance(myProject).restart();
}
- if (myTemplateLanguage.getSelectedItem() != myTemplatesModel.getTemplateLanguage()) {
- myTemplatesModel.apply();
- reparseFiles(Arrays.asList("html", "xml", "js")); //TODO: get from file extensions
- }
-
if (analyzeDoctest.isSelected() != myDocumentationSettings.analyzeDoctest) {
final List<VirtualFile> files = Lists.newArrayList();
ProjectRootManager.getInstance(myProject).getFileIndex().iterateContent(new ContentIterator() {
@@ -315,9 +297,6 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable, No
txtIsRst.setSelected(ReSTService.getInstance(myModule).txtIsRst());
analyzeDoctest.setSelected(myDocumentationSettings.analyzeDoctest);
myRequirementsPathField.setText(getRequirementsPath());
- myTemplateLanguage.setSelectedItem(myTemplatesModel.getTemplateLanguage());
- myTemplatesModel.reset();
-
}
@Override
diff --git a/python/src/com/jetbrains/python/configuration/TemplatesConfigurationsModel.java b/python/src/com/jetbrains/python/configuration/TemplatesConfigurationsModel.java
deleted file mode 100644
index 0722b36308e7..000000000000
--- a/python/src/com/jetbrains/python/configuration/TemplatesConfigurationsModel.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.jetbrains.python.configuration;
-
-import com.intellij.ui.CollectionComboBoxModel;
-import com.jetbrains.python.templateLanguages.TemplatesService;
-
-import java.util.List;
-
-/**
- * User: catherine
- */
-public class TemplatesConfigurationsModel extends CollectionComboBoxModel {
- private String myTemplateLanguage;
- private final TemplatesService myTemplatesService;
-
- public TemplatesConfigurationsModel(final List items, TemplatesService templatesService) {
- super(items, templatesService.getTemplateLanguage());
- myTemplatesService = templatesService;
- myTemplateLanguage = myTemplatesService.getTemplateLanguage();
- }
-
- public void reset() {
- setSelectedItem(myTemplateLanguage);
- }
-
- public void apply() {
- myTemplateLanguage = (String)getSelectedItem();
- myTemplatesService.setTemplateLanguage(myTemplateLanguage);
- }
-
- public Object getTemplateLanguage() {
- return myTemplateLanguage;
- }
-} \ No newline at end of file
diff --git a/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java b/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java
index b4d83600b7b9..8ef4ec9a47a4 100644
--- a/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java
+++ b/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java
@@ -137,13 +137,15 @@ public class PydevConsoleExecuteActionHandler extends ProcessBackedConsoleExecut
// multiline strings handling
if (myInMultilineStringState != null) {
- if (PyConsoleUtil.isDoubleQuoteMultilineStarts(line)) {
+ if (PyConsoleUtil.isDoubleQuoteMultilineStarts(line) || PyConsoleUtil.isSingleQuoteMultilineStarts(line)) {
myInMultilineStringState = null;
// restore language
console.setLanguage(PythonLanguage.getInstance());
console.setPrompt(PyConsoleUtil.ORDINARY_PROMPT);
- }
- else {
+ } else {
+ if(line.equals("\n")) {
+ myInputBuffer.append("\n");
+ }
return;
}
}
diff --git a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
index 213f63511eb6..c3f89cd0cd57 100644
--- a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
+++ b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
@@ -54,8 +54,8 @@ import com.intellij.openapi.vfs.encoding.EncodingManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.tree.FileElement;
-import com.intellij.remotesdk.RemoteSdkCredentials;
-import com.intellij.remotesdk.RemoteSshProcess;
+import com.intellij.remote.RemoteSdkCredentials;
+import com.intellij.remote.RemoteSshProcess;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IJSwingUtilities;
diff --git a/python/src/com/jetbrains/python/console/RunPythonConsoleAction.java b/python/src/com/jetbrains/python/console/RunPythonConsoleAction.java
index 9c610e768b28..728056cca301 100644
--- a/python/src/com/jetbrains/python/console/RunPythonConsoleAction.java
+++ b/python/src/com/jetbrains/python/console/RunPythonConsoleAction.java
@@ -221,7 +221,7 @@ public class RunPythonConsoleAction extends AnAction implements DumbAware {
final String path = Joiner.on(", ").join(Collections2.transform(pythonPath, new Function<String, String>() {
@Override
public String apply(String input) {
- return "'" + input.replace("\\", "\\\\") + "'";
+ return "'" + input.replace("\\", "\\\\").replace("'", "\\'") + "'";
}
}));
diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java
index 312db25573c8..0bae7af19732 100644
--- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java
+++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java
@@ -34,7 +34,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
-import com.intellij.remotesdk.RemoteProcessHandlerBase;
+import com.intellij.remote.RemoteProcessHandlerBase;
import com.intellij.xdebugger.*;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
diff --git a/python/src/com/jetbrains/python/debugger/PySmartStepIntoHandler.java b/python/src/com/jetbrains/python/debugger/PySmartStepIntoHandler.java
index af8b69f3b07e..5b1217072465 100644
--- a/python/src/com/jetbrains/python/debugger/PySmartStepIntoHandler.java
+++ b/python/src/com/jetbrains/python/debugger/PySmartStepIntoHandler.java
@@ -49,6 +49,7 @@ public class PySmartStepIntoHandler extends XSmartStepIntoHandler<PySmartStepInt
myProcess = process;
}
+ @Override
@NotNull
public List<PySmartStepIntoVariant> computeSmartStepVariants(@NotNull XSourcePosition position) {
final Document document = FileDocumentManager.getInstance().getDocument(position.getFile());
@@ -57,6 +58,7 @@ public class PySmartStepIntoHandler extends XSmartStepIntoHandler<PySmartStepInt
final int line = position.getLine();
XDebuggerUtil.getInstance().iterateLine(mySession.getProject(), document, line, new Processor<PsiElement>() {
+ @Override
public boolean process(PsiElement psiElement) {
addVariants(document, line, psiElement, variants, visitedCalls);
return true;
@@ -67,10 +69,11 @@ public class PySmartStepIntoHandler extends XSmartStepIntoHandler<PySmartStepInt
}
@Override
- public void startStepInto(PySmartStepIntoVariant smartStepIntoVariant) {
+ public void startStepInto(@NotNull PySmartStepIntoVariant smartStepIntoVariant) {
myProcess.startSmartStepInto(smartStepIntoVariant.getFunctionName());
}
+ @Override
public String getPopupTitle(@NotNull XSourcePosition position) {
return PyBundle.message("debug.popup.title.step.into.function");
}
diff --git a/python/src/com/jetbrains/python/debugger/PyStackFrame.java b/python/src/com/jetbrains/python/debugger/PyStackFrame.java
index 1c72e8b9e0d8..2c8727c12354 100644
--- a/python/src/com/jetbrains/python/debugger/PyStackFrame.java
+++ b/python/src/com/jetbrains/python/debugger/PyStackFrame.java
@@ -69,7 +69,7 @@ public class PyStackFrame extends XStackFrame {
}
@Override
- public void customizePresentation(ColoredTextContainer component) {
+ public void customizePresentation(@NotNull ColoredTextContainer component) {
component.setIcon(AllIcons.Debugger.StackFrame);
if (myPosition == null) {
diff --git a/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java b/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java
index ad1fa2d7f5a2..6934a37d723f 100644
--- a/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java
+++ b/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java
@@ -226,7 +226,7 @@ public class PyTypeModelBuilder {
parameterModels.add(new ParamType(parameter.getName(), build(parameter.getType(myContext), true)));
}
}
- final PyType ret = type.getCallType(myContext, null);
+ final PyType ret = type.getReturnType(myContext);
final TypeModel returnType = build(ret, true);
return new FunctionType(returnType, parameterModels);
}
diff --git a/python/src/com/jetbrains/python/findUsages/PyFindUsagesHandlerFactory.java b/python/src/com/jetbrains/python/findUsages/PyFindUsagesHandlerFactory.java
index 78d9d654ef77..82f2605ec5d8 100644
--- a/python/src/com/jetbrains/python/findUsages/PyFindUsagesHandlerFactory.java
+++ b/python/src/com/jetbrains/python/findUsages/PyFindUsagesHandlerFactory.java
@@ -99,6 +99,6 @@ public class PyFindUsagesHandlerFactory extends FindUsagesHandlerFactory {
return false;
}
return (PyNames.FAKE_OLD_BASE.equals(containingClass.getName()) ||
- (PyNames.OBJECT.equals(containingClass.getName()) && PyBuiltinCache.getInstance(fun).hasInBuiltins(containingClass)));
+ (PyNames.OBJECT.equals(containingClass.getName()) && PyBuiltinCache.getInstance(fun).isBuiltin(containingClass)));
}
}
diff --git a/python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java b/python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java
index 6a06f875b1b2..9b8b0891764d 100644
--- a/python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java
@@ -84,7 +84,7 @@ public class PyArgumentEqualDefaultInspection extends PyInspection {
private static boolean hasSpecialCasedDefaults(Callable callable, PsiElement anchor) {
final String name = callable.getName();
final PyBuiltinCache cache = PyBuiltinCache.getInstance(anchor);
- if ("getattr".equals(name) && cache.hasInBuiltins(callable)) {
+ if ("getattr".equals(name) && cache.isBuiltin(callable)) {
return true;
}
else if ("get".equals(name) || "pop".equals(name)) {
diff --git a/python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java b/python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java
index 2731f8d8fb11..4b0945d6742b 100644
--- a/python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java
@@ -54,7 +54,7 @@ public class PyBroadExceptionInspection extends PyInspection {
public static boolean equalsException(@NotNull PyClass cls, @NotNull TypeEvalContext context) {
final PyType type = context.getType(cls);
- return ("Exception".equals(cls.getName()) || "BaseException".equals(cls.getName())) && type != null && type.isBuiltin(context);
+ return ("Exception".equals(cls.getName()) || "BaseException".equals(cls.getName())) && type != null && type.isBuiltin();
}
private static class Visitor extends PyInspectionVisitor {
diff --git a/python/src/com/jetbrains/python/inspections/PyByteLiteralInspection.java b/python/src/com/jetbrains/python/inspections/PyByteLiteralInspection.java
index 536074e51d39..0b5c93c8dbaa 100644
--- a/python/src/com/jetbrains/python/inspections/PyByteLiteralInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyByteLiteralInspection.java
@@ -75,7 +75,7 @@ public class PyByteLiteralInspection extends PyInspection {
);
}
- final String charsetString = PythonFileType.getCharsetFromEncodingDeclaration(file.getText());
+ final String charsetString = PythonFileType.getCharsetFromEncodingDeclaration(file);
try {
if (charsetString != null && !Charset.forName(charsetString).equals(Charset.forName("US-ASCII")))
default_bytes = false;
diff --git a/python/src/com/jetbrains/python/inspections/PyComparisonWithNoneInspection.java b/python/src/com/jetbrains/python/inspections/PyComparisonWithNoneInspection.java
index 3883cd0a6f43..ec31c002a803 100644
--- a/python/src/com/jetbrains/python/inspections/PyComparisonWithNoneInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyComparisonWithNoneInspection.java
@@ -64,7 +64,7 @@ public class PyComparisonWithNoneInspection extends PyInspection {
PsiReference reference = node.getReference();
assert reference != null;
PsiElement result = reference.resolve();
- if (result == null || PyBuiltinCache.getInstance(node).hasInBuiltins(result)) {
+ if (result == null || PyBuiltinCache.getInstance(node).isBuiltin(result)) {
registerProblem(node, "Comparison with None performed with equality operators", new ComparisonWithNoneQuickFix());
}
}
diff --git a/python/src/com/jetbrains/python/inspections/PyInitNewSignatureInspection.java b/python/src/com/jetbrains/python/inspections/PyInitNewSignatureInspection.java
index 6ced1d18eae1..694d7ad17611 100644
--- a/python/src/com/jetbrains/python/inspections/PyInitNewSignatureInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyInitNewSignatureInspection.java
@@ -57,7 +57,7 @@ public class PyInitNewSignatureInspection extends PyInspection {
if (! cls.isNewStyleClass()) return; // old-style classes don't know about __new__
PyFunction init_or_new = cls.findInitOrNew(false); // only local
final PyBuiltinCache builtins = PyBuiltinCache.getInstance(cls);
- if (init_or_new == null || builtins.hasInBuiltins(init_or_new.getContainingClass())) return; // nothing is overridden
+ if (init_or_new == null || builtins.isBuiltin(init_or_new.getContainingClass())) return; // nothing is overridden
String the_other_name = PyNames.NEW.equals(init_or_new.getName()) ? PyNames.INIT : PyNames.NEW;
PyFunction the_other = cls.findMethodByName(the_other_name, true);
if (the_other == null || builtins.getClass("object") == the_other.getContainingClass()) return;
diff --git a/python/src/com/jetbrains/python/inspections/PyMandatoryEncodingInspection.java b/python/src/com/jetbrains/python/inspections/PyMandatoryEncodingInspection.java
index 58e97044c4ab..d41cfbeea3cb 100644
--- a/python/src/com/jetbrains/python/inspections/PyMandatoryEncodingInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyMandatoryEncodingInspection.java
@@ -62,7 +62,7 @@ public class PyMandatoryEncodingInspection extends PyInspection {
@Override
public void visitPyFile(PyFile node) {
- final String charsetString = PythonFileType.getCharsetFromEncodingDeclaration(node.getText());
+ final String charsetString = PythonFileType.getCharsetFromEncodingDeclaration(node);
if (charsetString == null) {
TextRange tr = new TextRange(0,0);
ProblemsHolder holder = getHolder();
diff --git a/python/src/com/jetbrains/python/inspections/PyMethodMayBeStaticInspection.java b/python/src/com/jetbrains/python/inspections/PyMethodMayBeStaticInspection.java
index 71f2772dae08..acf33c542e24 100644
--- a/python/src/com/jetbrains/python/inspections/PyMethodMayBeStaticInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyMethodMayBeStaticInspection.java
@@ -32,8 +32,6 @@ import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.Collection;
-
/**
* User: ktisha
*
@@ -66,10 +64,10 @@ public class PyMethodMayBeStaticInspection extends PyInspection {
final PyClass containingClass = node.getContainingClass();
if (containingClass == null) return;
if (PythonUnitTestUtil.isUnitTestCaseClass(containingClass)) return;
- final Collection<PsiElement> supers = PySuperMethodsSearch.search(node).findAll();
- if (!supers.isEmpty()) return;
- final Collection<PyFunction> overrides = PyOverridingMethodsSearch.search(node, true).findAll();
- if (!overrides.isEmpty()) return;
+ final PsiElement firstSuper = PySuperMethodsSearch.search(node).findFirst();
+ if (firstSuper != null) return;
+ final PyFunction firstOverride = PyOverridingMethodsSearch.search(node, true).findFirst();
+ if (firstOverride != null) return;
final PyDecoratorList decoratorList = node.getDecoratorList();
if (decoratorList != null) return;
if (node.getModifier() != null) return;
diff --git a/python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java b/python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java
index 3038b64710d1..5fd0e565a6f8 100644
--- a/python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java
@@ -69,7 +69,7 @@ public class PyNonAsciiCharInspection extends PyInspection {
if (LanguageLevel.forElement(node).isPy3K()) return;
PsiFile file = node.getContainingFile(); // can't cache this in the instance, alas
if (file == null) return;
- final String charsetString = PythonFileType.getCharsetFromEncodingDeclaration(file.getText());
+ final String charsetString = PythonFileType.getCharsetFromEncodingDeclaration(file);
boolean hasNonAscii = false;
diff --git a/python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java b/python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java
index f3fddbac3a8b..1b3dfc63b61f 100644
--- a/python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyPep8NamingInspection.java
@@ -24,7 +24,8 @@ import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.QualifiedName;
import com.intellij.util.containers.hash.HashMap;
-import com.intellij.util.containers.hash.HashSet;
+import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
+import com.jetbrains.python.codeInsight.dataflow.scope.Scope;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
import com.jetbrains.python.psi.types.PyModuleType;
@@ -34,9 +35,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.Collection;
import java.util.Map;
-import java.util.Set;
import java.util.regex.Pattern;
/**
@@ -71,17 +70,10 @@ public class PyPep8NamingInspection extends PyInspection {
public void visitPyAssignmentStatement(PyAssignmentStatement node) {
final PyFunction function = PsiTreeUtil.getParentOfType(node, PyFunction.class, true, PyClass.class);
if (function == null) return;
- final Collection<PyGlobalStatement> globalStatements = PsiTreeUtil.findChildrenOfType(function, PyGlobalStatement.class);
- final Set<String> globals = new HashSet<String>();
- for (PyGlobalStatement statement : globalStatements) {
- final PyTargetExpression[] statementGlobals = statement.getGlobals();
- for (PyTargetExpression global : statementGlobals) {
- globals.add(global.getName());
- }
- }
+ final Scope scope = ControlFlowCache.getScope(function);
for (PyExpression expression : node.getTargets()) {
final String name = expression.getName();
- if (name == null || globals.contains(name)) continue;
+ if (name == null || scope.isGlobal(name)) continue;
if (expression instanceof PyTargetExpression) {
final PyExpression qualifier = ((PyTargetExpression)expression).getQualifier();
if (qualifier != null) {
diff --git a/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java b/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java
index 967e6a47c26d..27fff5602374 100644
--- a/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java
@@ -301,7 +301,9 @@ public class PyPropertyDefinitionInspection extends PyInspection {
}
else {
PyReferenceExpression callSite = being_checked instanceof PyReferenceExpression ? (PyReferenceExpression) being_checked : null;
- hasReturns = !(callable.getReturnType(myTypeEvalContext, callSite) instanceof PyNoneType);
+ final PyType type = callSite != null ? callable.getCallType(myTypeEvalContext, callSite)
+ : myTypeEvalContext.getReturnType(callable);
+ hasReturns = !(type instanceof PyNoneType);
}
if (allowed ^ hasReturns) {
if (allowed && callable instanceof PyFunction) {
diff --git a/python/src/com/jetbrains/python/inspections/PyProtectedMemberInspection.java b/python/src/com/jetbrains/python/inspections/PyProtectedMemberInspection.java
index fe9ac7f9159e..52775764074e 100644
--- a/python/src/com/jetbrains/python/inspections/PyProtectedMemberInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyProtectedMemberInspection.java
@@ -70,7 +70,10 @@ public class PyProtectedMemberInspection extends PyInspection {
if (name != null && name.startsWith("_") && !name.startsWith("__") && !name.endsWith("__")) {
final PyClass parentClass = getClassOwner(node);
if (parentClass != null) {
- final PsiReference reference = node.getReference();
+ final PsiReference reference = node.getReference(resolveWithoutImplicits());
+ if (reference == null) {
+ return;
+ }
final PsiElement resolvedExpression = reference.resolve();
final PyClass resolvedClass = getClassOwner(resolvedExpression);
if (parentClass.isSubclass(resolvedClass))
diff --git a/python/src/com/jetbrains/python/inspections/PySetFunctionToLiteralInspection.java b/python/src/com/jetbrains/python/inspections/PySetFunctionToLiteralInspection.java
index f0bdeb399a1b..e846fdba3c19 100644
--- a/python/src/com/jetbrains/python/inspections/PySetFunctionToLiteralInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PySetFunctionToLiteralInspection.java
@@ -22,9 +22,7 @@ import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.openapi.util.JDOMExternalizableStringList;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
-import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
-import com.intellij.psi.PsiReference;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.inspections.quickfix.ReplaceFunctionWithSetLiteralQuickFix;
@@ -66,7 +64,7 @@ public class PySetFunctionToLiteralInspection extends PyInspection {
public void visitPyCallExpression(final PyCallExpression node) {
if (!isAvailable(node)) return;
PyExpression callee = node.getCallee();
- if (node.isCalleeText(PyNames.SET) && isInBuiltins(callee)) {
+ if (node.isCalleeText(PyNames.SET) && callee != null && PyBuiltinCache.isInBuiltins(callee)) {
PyExpression[] arguments = node.getArguments();
if (arguments.length == 1) {
PyElement[] elements = getSetCallArguments(node);
@@ -91,20 +89,6 @@ public class PySetFunctionToLiteralInspection extends PyInspection {
}
return LanguageLevel.forElement(node).supportsSetLiterals();
}
-
- private static boolean isInBuiltins(PyExpression callee) {
- if (callee instanceof PyQualifiedExpression && (((PyQualifiedExpression)callee).isQualified())) {
- return false;
- }
- PsiReference reference = callee.getReference();
- if (reference != null) {
- PsiElement resolved = reference.resolve();
- if (resolved != null && PyBuiltinCache.getInstance(callee).hasInBuiltins(resolved)) {
- return true;
- }
- }
- return false;
- }
}
public static PyElement[] getSetCallArguments(PyCallExpression node) {
diff --git a/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java b/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java
index 28ccafd5aa12..a72ec9ef8504 100644
--- a/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java
@@ -111,7 +111,7 @@ public class PyStatementEffectInspection extends PyInspection {
// maybe the op is overridden and may produce side effects, like cout << "hello"
PyType type = myTypeEvalContext.getType(leftExpression);
if (type != null &&
- !type.isBuiltin(myTypeEvalContext) &&
+ !type.isBuiltin() &&
type.resolveMember(method, null, AccessDirection.READ, resolveWithoutImplicits()) != null) {
return true;
}
@@ -119,7 +119,7 @@ public class PyStatementEffectInspection extends PyInspection {
type = myTypeEvalContext.getType(rightExpression);
if (type != null) {
String rmethod = "__r" + method.substring(2); // __add__ -> __radd__
- if (!type.isBuiltin(myTypeEvalContext) && type.resolveMember(rmethod, null, AccessDirection.READ, resolveWithoutImplicits()) != null) {
+ if (!type.isBuiltin() && type.resolveMember(rmethod, null, AccessDirection.READ, resolveWithoutImplicits()) != null) {
return true;
}
}
diff --git a/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java b/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java
index 180fd1bfc3b0..280822ba7175 100644
--- a/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java
@@ -149,7 +149,7 @@ public class PyStringFormatInspection extends PyInspection {
}
else if (rightExpression instanceof PyCallExpression) {
final Callable callable = ((PyCallExpression)rightExpression).resolveCalleeFunction(resolveContext);
- // TODO: Switch to Callable.getReturnType()
+ // TODO: Switch to Callable.getCallType()
if (callable instanceof PyFunction && myTypeEvalContext.maySwitchToAST((PyFunction) callable)) {
PyStatementList statementList = ((PyFunction)callable).getStatementList();
if (statementList == null) {
diff --git a/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java b/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java
index 45df382d3f83..d31d19ef4da9 100644
--- a/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java
@@ -102,7 +102,7 @@ public class PyTypeCheckerInspection extends PyInspection {
}
final PyType argType = myTypeEvalContext.getType(entry.getKey());
if (!genericsCollected) {
- substitutions.putAll(PyTypeChecker.collectCallGenerics(results.getCallable(), results.getReceiver(), myTypeEvalContext));
+ substitutions.putAll(PyTypeChecker.unifyReceiver(results.getReceiver(), myTypeEvalContext));
genericsCollected = true;
}
checkTypes(paramType, argType, entry.getKey(), myTypeEvalContext, substitutions);
diff --git a/python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java b/python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java
index abec5b165fb9..9e0031afec84 100644
--- a/python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java
@@ -132,7 +132,7 @@ public class PyUnboundLocalVariableInspection extends PyInspection {
return;
}
final PsiElement resolved = ref.resolve();
- final boolean isBuiltin = PyBuiltinCache.getInstance(node).hasInBuiltins(resolved);
+ final boolean isBuiltin = PyBuiltinCache.getInstance(node).isBuiltin(resolved);
if (owner instanceof PyClass) {
if (isBuiltin || ScopeUtil.getDeclarationScopeOwner(owner, name) != null) {
return;
diff --git a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java
index 9e08a47eafc9..2e33a1f175b1 100644
--- a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java
@@ -749,7 +749,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
PsiElement element = reference.getElement();
if (type instanceof PyClassTypeImpl) {
PyClass cls = ((PyClassType)type).getPyClass();
- if (!PyBuiltinCache.getInstance(element).hasInBuiltins(cls)) {
+ if (!PyBuiltinCache.getInstance(element).isBuiltin(cls)) {
if (element.getParent() instanceof PyCallExpression) {
actions.add(new AddMethodQuickFix(refText, (PyClassType)type, true));
}
@@ -886,7 +886,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
return true;
}
method = resolveClassMember(cls, PyNames.GETATTRIBUTE, context);
- if (method != null && !PyBuiltinCache.getInstance(cls).hasInBuiltins(method)) {
+ if (method != null && !PyBuiltinCache.getInstance(cls).isBuiltin(method)) {
return true;
}
return false;
diff --git a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java
index f7883535d2e6..3dc42057348f 100644
--- a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java
+++ b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java
@@ -328,7 +328,7 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor {
PyCallExpression expr = (PyCallExpression) source;
if (expr.isCalleeText("range", "xrange")) {
final Callable callee = expr.resolveCalleeFunction(PyResolveContext.noImplicits().withTypeEvalContext(myTypeEvalContext));
- if (callee != null && PyBuiltinCache.getInstance(forStatement).hasInBuiltins(callee)) {
+ if (callee != null && PyBuiltinCache.getInstance(forStatement).isBuiltin(callee)) {
return true;
}
}
diff --git a/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java b/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java
index 82a5fd9590ac..fe4ab8f910ef 100644
--- a/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java
+++ b/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java
@@ -49,8 +49,9 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
-import com.intellij.remotesdk.RemoteFile;
-import com.intellij.remotesdk.RemoteSdkCredentials;
+import com.intellij.remote.RemoteSdkAdditionalData;
+import com.intellij.remote.RemoteFile;
+import com.intellij.remote.RemoteSdkCredentials;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.SystemProperties;
@@ -778,10 +779,17 @@ public class PyPackageManagerImpl extends PyPackageManager {
if (homePath == null) {
throw new PyExternalProcessException(ERROR_INVALID_SDK, helperPath, args, "Cannot find interpreter for SDK");
}
- if (sdkData instanceof RemoteSdkCredentials) { //remote interpreter
- final RemoteSdkCredentials remoteSdkCredentials = (RemoteSdkCredentials)sdkData;
+ if (sdkData instanceof RemoteSdkAdditionalData) { //remote interpreter
+ RemoteSdkCredentials remoteSdkCredentials;
+ try {
+ remoteSdkCredentials = ((RemoteSdkAdditionalData)sdkData).getRemoteSdkCredentials();
+ }
+ catch (InterruptedException e) {
+ LOG.error(e);
+ remoteSdkCredentials = null;
+ }
final PythonRemoteInterpreterManager manager = PythonRemoteInterpreterManager.getInstance();
- if (manager != null) {
+ if (manager != null && remoteSdkCredentials != null) {
final List<String> cmdline = new ArrayList<String>();
cmdline.add(homePath);
cmdline.add(RemoteFile.detectSystemByPath(homePath).createRemoteFile(helperPath).getPath());
diff --git a/python/src/com/jetbrains/python/packaging/ui/PyInstalledPackagesPanel.java b/python/src/com/jetbrains/python/packaging/ui/PyInstalledPackagesPanel.java
index d894786b7dd6..0fdbc53a5586 100644
--- a/python/src/com/jetbrains/python/packaging/ui/PyInstalledPackagesPanel.java
+++ b/python/src/com/jetbrains/python/packaging/ui/PyInstalledPackagesPanel.java
@@ -33,8 +33,8 @@ import com.jetbrains.python.sdk.PythonSdkType;
import com.jetbrains.python.sdk.flavors.IronPythonSdkFlavor;
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import java.awt.*;
import java.util.List;
import java.util.Set;
@@ -51,8 +51,6 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
public PyInstalledPackagesPanel(Project project, PackagesNotificationPanel area) {
super(project, area);
- setPreferredSize(new Dimension(500, 500));
-
myNotificationArea.addLinkHandler(INSTALL_SETUPTOOLS, new Runnable() {
@Override
public void run() {
@@ -78,7 +76,11 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
return service != null ? service.getSdk() : null;
}
- public void updateNotifications(@NotNull final Sdk selectedSdk) {
+ public void updateNotifications(@Nullable final Sdk selectedSdk) {
+ if (selectedSdk == null) {
+ myNotificationArea.hide();
+ return;
+ }
final Application application = ApplicationManager.getApplication();
application.executeOnPooledThread(new Runnable() {
@Override
diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java
index 83036eec8626..97b380b4f381 100644
--- a/python/src/com/jetbrains/python/psi/PyUtil.java
+++ b/python/src/com/jetbrains/python/psi/PyUtil.java
@@ -857,7 +857,10 @@ public class PyUtil {
*
* @param elt starting point of search.
* @return 'class' or 'def' element, or null if not found.
+ *
+ * @deprecated Use {@link ScopeUtil#getScopeOwner} instead.
*/
+ @Deprecated
@Nullable
public static PsiElement getConcealingParent(PsiElement elt) {
if (elt == null || elt instanceof PsiFile) {
@@ -1138,7 +1141,7 @@ public class PyUtil {
if (reference == null) return false;
PsiElement resolved = reference.resolve();
PyBuiltinCache cache = PyBuiltinCache.getInstance(node);
- if (resolved != null && cache.hasInBuiltins(resolved)) {
+ if (resolved != null && cache.isBuiltin(resolved)) {
PyExpression[] args = node.getArguments();
if (args.length > 0) {
String firstArg = args[0].getText();
diff --git a/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java b/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java
index 692ff0052b10..20e8c5dbe1dc 100644
--- a/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java
@@ -134,7 +134,7 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping {
}
else {
PyType arg_type = context.getType(arg);
- if (arg_type != null && arg_type.isBuiltin(context) && "list".equals(arg_type.getName())) {
+ if (arg_type != null && arg_type.isBuiltin() && "list".equals(arg_type.getName())) {
mapped_args.add(arg); // we can't really analyze arbitrary lists statically yet
// but ListLiteralExpressions are handled by visitor
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyArgumentListImpl.java b/python/src/com/jetbrains/python/psi/impl/PyArgumentListImpl.java
index dfe12ca6dc30..2e6120a29303 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyArgumentListImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyArgumentListImpl.java
@@ -48,6 +48,23 @@ public class PyArgumentListImpl extends PyElementImpl implements PyArgumentList
pyVisitor.visitPyArgumentList(this);
}
+ @Override
+ @NotNull
+ public Collection<PyExpression> getArgumentExpressions() {
+ final PyExpression[] arguments = getArguments();
+ final Collection<PyExpression> result = new ArrayList<PyExpression>(arguments.length);
+ for (final PyExpression expression : arguments) {
+ if (expression instanceof PyKeywordArgument) {
+ final PyExpression valueExpression = ((PyKeywordArgument)expression).getValueExpression();
+ result.add(valueExpression);
+ }
+ if (expression instanceof PyReferenceExpression) {
+ result.add(expression);
+ }
+ }
+ return result;
+ }
+
@NotNull
public PyExpression[] getArguments() {
return childrenToPsi(PythonDialectsTokenSetProvider.INSTANCE.getExpressionTokens(), PyExpression.EMPTY_ARRAY);
diff --git a/python/src/com/jetbrains/python/psi/impl/PyBinaryExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyBinaryExpressionImpl.java
index bee876ac948d..61513d1e4c4f 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyBinaryExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyBinaryExpressionImpl.java
@@ -137,7 +137,7 @@ public class PyBinaryExpressionImpl extends PyElementImpl implements PyBinaryExp
}
final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCall(this, context);
if (results != null) {
- final PyType type = results.getCallable().getReturnType(context, this);
+ final PyType type = results.getCallable().getCallType(context, this);
if (!PyTypeChecker.isUnknown(type) && !(type instanceof PyNoneType)) {
return type;
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java
index b545290c13c6..0f4b0813cf7c 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java
@@ -27,15 +27,9 @@ import com.intellij.openapi.roots.impl.ModuleLibraryOrderEntryImpl;
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.psi.PsiFileSystemItem;
-import com.intellij.psi.PsiManager;
+import com.intellij.psi.*;
import com.jetbrains.python.PyNames;
-import com.jetbrains.python.psi.LanguageLevel;
-import com.jetbrains.python.psi.PyClass;
-import com.jetbrains.python.psi.PyFile;
-import com.jetbrains.python.psi.PySequenceExpression;
+import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.resolve.PythonSdkPathCache;
import com.jetbrains.python.psi.types.*;
import com.jetbrains.python.sdk.PythonSdkType;
@@ -183,7 +177,13 @@ public class PyBuiltinCache {
@Nullable
public PsiElement getByName(@NonNls String name) {
if (myBuiltinsFile != null) {
- return myBuiltinsFile.getElementNamed(name);
+ final PsiElement element = myBuiltinsFile.getElementNamed(name);
+ if (element != null) {
+ return element;
+ }
+ }
+ if (myExceptionsFile != null) {
+ return myExceptionsFile.getElementNamed(name);
}
return null;
}
@@ -337,7 +337,7 @@ public class PyBuiltinCache {
* @param target an element to check.
* @return true iff target is inside the __builtins__.py
*/
- public boolean hasInBuiltins(@Nullable PsiElement target) {
+ public boolean isBuiltin(@Nullable PsiElement target) {
if (target == null) return false;
if (! target.isValid()) return false;
final PsiFile the_file = target.getContainingFile();
@@ -347,4 +347,22 @@ public class PyBuiltinCache {
// files are singletons, no need to compare URIs
return the_file == myBuiltinsFile || the_file == myExceptionsFile;
}
+
+ public static boolean isInBuiltins(@NotNull PyExpression expression) {
+ if (expression instanceof PyQualifiedExpression && (((PyQualifiedExpression)expression).isQualified())) {
+ return false;
+ }
+ final String name = expression.getName();
+ PsiReference reference = expression.getReference();
+ if (reference != null && name != null) {
+ final PyBuiltinCache cache = getInstance(expression);
+ if (cache.getByName(name) != null) {
+ final PsiElement resolved = reference.resolve();
+ if (resolved != null && cache.isBuiltin(resolved)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java
index 781dc28c0d35..45f094764533 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java
@@ -198,7 +198,7 @@ public class PyCallExpressionHelper {
final PyFunction function = (PyFunction)resolved;
final Property property = function.getProperty();
if (property != null && isQualifiedByInstance(function, qualifiers, context)) {
- final PyType type = function.getReturnType(context, null);
+ final PyType type = context.getReturnType(function);
if (type instanceof PyFunctionType) {
resolved = ((PyFunctionType)type).getCallable();
}
@@ -424,7 +424,7 @@ public class PyCallExpressionHelper {
}
}
if (init != null) {
- final PyType t = init.getReturnType(context, (PyReferenceExpression)callee);
+ final PyType t = init.getCallType(context, (PyReferenceExpression)callee);
if (cls != null) {
if (init.getContainingClass() != cls) {
if (t instanceof PyCollectionType) {
@@ -439,7 +439,7 @@ public class PyCallExpressionHelper {
}
if (cls != null && t == null) {
final PyFunction newMethod = cls.findMethodByName(PyNames.NEW, true);
- if (newMethod != null && !PyBuiltinCache.getInstance(call).hasInBuiltins(newMethod)) {
+ if (newMethod != null && !PyBuiltinCache.getInstance(call).isBuiltin(newMethod)) {
return PyUnionType.createWeakType(new PyClassTypeImpl(cls, false));
}
}
@@ -453,7 +453,7 @@ public class PyCallExpressionHelper {
}
if (target instanceof Callable) {
final Callable callable = (Callable)target;
- return callable.getReturnType(context, (PyReferenceExpression)callee);
+ return callable.getCallType(context, (PyReferenceExpression)callee);
}
}
}
@@ -463,8 +463,14 @@ public class PyCallExpressionHelper {
else {
final PyType type = context.getType(callee);
if (type instanceof PyCallableType) {
+ final PyCallableType callableType = (PyCallableType)type;
final PyQualifiedExpression callSite = callee instanceof PyQualifiedExpression ? (PyQualifiedExpression)callee : null;
- return ((PyCallableType) type).getCallType(context, callSite);
+ if (callSite != null) {
+ return callableType.getCallType(context, callSite);
+ }
+ else {
+ return callableType.getReturnType(context);
+ }
}
return null;
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
index bea0e10312bb..eaa480be1ac7 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
@@ -381,6 +381,13 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
}
@Override
+ @NotNull
+ public Map<String, Property> getProperties() {
+ initProperties();
+ return new HashMap<String, Property>(myPropertyCache);
+ }
+
+ @Override
public PyClass[] getNestedClasses() {
return getClassChildren(TokenSet.create(PyElementTypes.CLASS_DECLARATION), PyClass.ARRAY_FACTORY);
}
@@ -607,9 +614,7 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
@Override
public Property findPropertyByCallable(Callable callable) {
- if (myPropertyCache == null) {
- myPropertyCache = initializePropertyCache();
- }
+ initProperties();
for (Property property : myPropertyCache.values()) {
if (property.getGetter().valueOrNull() == callable ||
property.getSetter().valueOrNull() == callable ||
@@ -621,10 +626,14 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
}
private Property findLocalProperty(String name) {
+ initProperties();
+ return myPropertyCache.get(name);
+ }
+
+ private synchronized void initProperties() {
if (myPropertyCache == null) {
myPropertyCache = initializePropertyCache();
}
- return myPropertyCache.get(name);
}
private Map<String, Property> initializePropertyCache() {
@@ -750,7 +759,7 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
if (!(callable instanceof StubBasedPsiElement) && !context.maySwitchToAST(callable)) {
return null;
}
- return callable.getReturnType(context, null);
+ return context.getReturnType(callable);
}
return null;
}
@@ -1149,7 +1158,7 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
}
}
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(this);
- if (result.isEmpty() && isValid() && !builtinCache.hasInBuiltins(this)) {
+ if (result.isEmpty() && isValid() && !builtinCache.isBuiltin(this)) {
final String implicitSuperName = LanguageLevel.forElement(this).isPy3K() ? PyNames.OBJECT : PyNames.FAKE_OLD_BASE;
final PyClass implicitSuper = builtinCache.getClass(implicitSuperName);
if (implicitSuper != null) {
diff --git a/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java b/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java
index 92e75ed21a5a..9e8ef1aa8c69 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java
@@ -65,7 +65,7 @@ public class PyDecoratorImpl extends StubBasedPsiElementBase<PyDecoratorStub> im
if (node != null) {
PyReferenceExpression ref = (PyReferenceExpression)node.getPsi();
PsiElement target = ref.getReference().resolve();
- return PyBuiltinCache.getInstance(this).hasInBuiltins(target);
+ return PyBuiltinCache.getInstance(this).isBuiltin(target);
}
return false;
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
index 2ffc8e6cba03..acc225b67f22 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
@@ -15,7 +15,6 @@
*/
package com.jetbrains.python.psi.impl;
-import com.google.common.collect.Maps;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.Pair;
@@ -176,42 +175,74 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
@Nullable
@Override
- public PyType getReturnType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
- PyType type = getGenericReturnType(context, callSite);
- if (callSite == null) {
- return type;
+ public PyType getReturnType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) {
+ for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
+ final PyType returnType = typeProvider.getReturnType(this, context);
+ if (returnType != null) {
+ returnType.assertValid(typeProvider.toString());
+ return returnType;
+ }
}
- final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCallSite(callSite, context);
- if (PyTypeChecker.hasGenerics(type, context)) {
- if (results != null) {
- final Map<PyGenericType, PyType> substitutions = PyTypeChecker.unifyGenericCall(this, results.getReceiver(), results.getArguments(),
- context);
- type = substitutions != null ? PyTypeChecker.substitute(type, substitutions, context) : null;
+ if (context.maySwitchToAST(this) && LanguageLevel.forElement(this).isAtLeast(LanguageLevel.PYTHON30)) {
+ PyAnnotation anno = getAnnotation();
+ if (anno != null) {
+ PyClass pyClass = anno.resolveToClass();
+ if (pyClass != null) {
+ return new PyClassTypeImpl(pyClass, false);
+ }
}
- else {
- type = null;
+ }
+ final PyType docStringType = getReturnTypeFromDocString();
+ if (docStringType != null) {
+ docStringType.assertValid("from docstring");
+ return docStringType;
+ }
+ if (context.allowReturnTypes(this)) {
+ final Ref<? extends PyType> yieldTypeRef = getYieldStatementType(context);
+ if (yieldTypeRef != null) {
+ return yieldTypeRef.get();
}
+ return getReturnStatementType(context);
}
- if (results != null) {
- type = replaceSelf(type, results.getReceiver(), context);
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ PyType type = null;
+ for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
+ type = typeProvider.getCallType(this, callSite, context);
+ if (type != null) {
+ type.assertValid(typeProvider.toString());
+ break;
+ }
}
- if (results != null && isDynamicallyEvaluated(results.getArguments().values(), context)) {
- return PyUnionType.createWeakType(type);
+ if (type == null) {
+ type = context.getReturnType(this);
+ }
+ final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCallSite(callSite, context);
+ if (results != null) {
+ return analyzeCallType(type, results.getReceiver(), results.getArguments(), context);
}
return type;
}
@Nullable
- /**
- * Suits when there is no call site(e.g. implicit __iter__ call in statement for)
- */
- public PyType getReturnTypeWithoutCallSite(@NotNull TypeEvalContext context,
- @Nullable PyExpression receiver) {
- PyType type = getGenericReturnType(context, null);
+ @Override
+ public PyType getCallType(@Nullable PyExpression receiver,
+ @NotNull Map<PyExpression, PyNamedParameter> parameters,
+ @NotNull TypeEvalContext context) {
+ return analyzeCallType(context.getReturnType(this), receiver, parameters, context);
+ }
+
+ @Nullable
+ private PyType analyzeCallType(@Nullable PyType type,
+ @Nullable PyExpression receiver,
+ @NotNull Map<PyExpression, PyNamedParameter> parameters,
+ @NotNull TypeEvalContext context) {
if (PyTypeChecker.hasGenerics(type, context)) {
- final Map<PyGenericType, PyType> substitutions = PyTypeChecker.unifyGenericCall(this, receiver,
- Maps.<PyExpression, PyNamedParameter>newHashMap(),
- context);
+ final Map<PyGenericType, PyType> substitutions = PyTypeChecker.unifyGenericCall(receiver, parameters, context);
if (substitutions != null) {
type = PyTypeChecker.substitute(type, substitutions, context);
}
@@ -219,7 +250,13 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
type = null;
}
}
- return replaceSelf(type, receiver, context);
+ if (receiver != null) {
+ type = replaceSelf(type, receiver, context);
+ }
+ if (type != null && isDynamicallyEvaluated(parameters.values(), context)) {
+ type = PyUnionType.createWeakType(type);
+ }
+ return type;
}
@Nullable
@@ -250,39 +287,6 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
}
@Nullable
- private PyType getGenericReturnType(@NotNull TypeEvalContext typeEvalContext, @Nullable PyQualifiedExpression callSite) {
- if (typeEvalContext.maySwitchToAST(this) && LanguageLevel.forElement(this).isAtLeast(LanguageLevel.PYTHON30)) {
- PyAnnotation anno = getAnnotation();
- if (anno != null) {
- PyClass pyClass = anno.resolveToClass();
- if (pyClass != null) {
- return new PyClassTypeImpl(pyClass, false);
- }
- }
- }
- for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
- final PyType returnType = typeProvider.getReturnType(this, callSite, typeEvalContext);
- if (returnType != null) {
- returnType.assertValid(typeProvider.toString());
- return returnType;
- }
- }
- final PyType docStringType = getReturnTypeFromDocString();
- if (docStringType != null) {
- docStringType.assertValid("from docstring");
- return docStringType;
- }
- if (typeEvalContext.allowReturnTypes(this)) {
- final Ref<? extends PyType> yieldTypeRef = getYieldStatementType(typeEvalContext);
- if (yieldTypeRef != null) {
- return yieldTypeRef.get();
- }
- return getReturnStatementType(typeEvalContext);
- }
- return null;
- }
-
- @Nullable
private Ref<? extends PyType> getYieldStatementType(@NotNull final TypeEvalContext context) {
Ref<PyType> elementType = null;
final PyBuiltinCache cache = PyBuiltinCache.getInstance(this);
@@ -386,8 +390,9 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
return type;
}
}
+ final boolean hasCustomDecorators = PyUtil.hasCustomDecorators(this) && !PyUtil.isDecoratedAsAbstract(this) && getProperty() == null;
final PyFunctionType type = new PyFunctionType(this);
- if (getDecoratorList() != null) {
+ if (hasCustomDecorators) {
return PyUnionType.createWeakType(type);
}
return type;
diff --git a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java
index 56249f1fdfa4..0dd75915de12 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java
@@ -27,6 +27,8 @@ import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Map;
+
/**
* @author yole
*/
@@ -61,10 +63,23 @@ public class PyLambdaExpressionImpl extends PyElementImpl implements PyLambdaExp
@Nullable
@Override
- public PyType getReturnType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
+ public PyType getReturnType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) {
final PyExpression body = getBody();
- if (body != null) return context.getType(body);
- else return null;
+ return body != null ? context.getType(body) : null;
+ }
+
+ @Nullable
+ @Override
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ return context.getReturnType(this);
+ }
+
+ @Nullable
+ @Override
+ public PyType getCallType(@Nullable PyExpression receiver,
+ @NotNull Map<PyExpression, PyNamedParameter> parameters,
+ @NotNull TypeEvalContext context) {
+ return context.getReturnType(this);
}
@Nullable
diff --git a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java
index 6ad33d60569e..f38937daa87f 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java
@@ -208,7 +208,7 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl<PyNamedParame
PyType initType = null;
final PyFunction init = containingClass.findInitOrNew(true);
if (init != null && init != func) {
- initType = init.getReturnType(context, null);
+ initType = context.getReturnType(init);
if (init.getContainingClass() != containingClass) {
if (initType instanceof PyCollectionType) {
final PyType elementType = ((PyCollectionType)initType).getElementType(context);
diff --git a/python/src/com/jetbrains/python/psi/impl/PyPrefixExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyPrefixExpressionImpl.java
index 71658f075451..79535f21f3f4 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyPrefixExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyPrefixExpressionImpl.java
@@ -88,7 +88,7 @@ public class PyPrefixExpressionImpl extends PyElementImpl implements PyPrefixExp
if (ref != null) {
final PsiElement resolved = ref.resolve();
if (resolved instanceof Callable) {
- return ((Callable)resolved).getReturnType(context, this);
+ return ((Callable)resolved).getCallType(context, this);
}
}
return null;
diff --git a/python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java
index 61438286bb8b..2b21e17ee0f8 100644
--- a/python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java
@@ -71,7 +71,7 @@ public class PySubscriptionExpressionImpl extends PyElementImpl implements PySub
if (ref != null) {
final PsiElement resolved = ref.resolve();
if (resolved instanceof Callable) {
- res = ((Callable)resolved).getReturnType(context, this);
+ res = ((Callable)resolved).getCallType(context, this);
}
}
if (PyTypeChecker.isUnknown(res) || res instanceof PyNoneType) {
diff --git a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
index c56111e612f7..060c39ccdee0 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
@@ -54,6 +54,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
/**
@@ -243,8 +244,8 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
if (exprType instanceof PyClassType) {
final PyClass cls = ((PyClassType)exprType).getPyClass();
final PyFunction enter = cls.findMethodByName(PyNames.ENTER, true);
- if (enter instanceof PyFunctionImpl) {
- final PyType enterType = ((PyFunctionImpl)enter).getReturnTypeWithoutCallSite(context, expression);
+ if (enter != null) {
+ final PyType enterType = enter.getCallType(expression, Collections.<PyExpression, PyNamedParameter>emptyMap(), context);
if (enterType != null) {
return enterType;
}
@@ -438,10 +439,7 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
@Nullable
private static PyType getContextSensitiveType(@NotNull PyFunction function, @NotNull TypeEvalContext context,
@Nullable PyExpression source) {
- if (function instanceof PyFunctionImpl) {
- return ((PyFunctionImpl)function).getReturnTypeWithoutCallSite(context, source);
- }
- return function.getReturnType(context, null);
+ return function.getCallType(source, Collections.<PyExpression, PyNamedParameter>emptyMap(), context);
}
@Nullable
diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java b/python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java
index e66a219062b6..a537dae722c1 100644
--- a/python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java
+++ b/python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java
@@ -212,7 +212,7 @@ public class PyQualifiedReference extends PyReferenceImpl {
PyExpression callee = ((PyCallExpression)qualifier).getCallee();
if (callee instanceof PyReferenceExpression && PyNames.SUPER.equals(callee.getName())) {
PsiElement target = ((PyReferenceExpression)callee).getReference().resolve();
- if (target != null && PyBuiltinCache.getInstance(qualifier).hasInBuiltins(target)) return false; // super() of unresolved type
+ if (target != null && PyBuiltinCache.getInstance(qualifier).isBuiltin(target)) return false; // super() of unresolved type
}
}
}
diff --git a/python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java b/python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java
index 3987e4e03032..bfa402449853 100644
--- a/python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java
+++ b/python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java
@@ -124,7 +124,7 @@ public class CompletionVariantsProcessor extends VariantsProcessor {
// special case hack to avoid the need of patching generator3.py
PyClass containingClass = callee.getContainingClass();
if (containingClass != null && PyNames.PROPERTY.equals(containingClass.getName()) &&
- PyBuiltinCache.getInstance(elementInCall).hasInBuiltins(containingClass)) {
+ PyBuiltinCache.getInstance(elementInCall).isBuiltin(containingClass)) {
return true;
}
diff --git a/python/src/com/jetbrains/python/psi/stubs/PyModuleNameIndex.java b/python/src/com/jetbrains/python/psi/stubs/PyModuleNameIndex.java
index 105aec5c0f7b..f743b8ec19f2 100644
--- a/python/src/com/jetbrains/python/psi/stubs/PyModuleNameIndex.java
+++ b/python/src/com/jetbrains/python/psi/stubs/PyModuleNameIndex.java
@@ -70,11 +70,13 @@ public class PyModuleNameIndex extends ScalarIndexExtension<String> {
return myDataIndexer;
}
+ @NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return myKeyDescriptor;
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new DefaultFileTypeSpecificInputFilter(PythonFileType.INSTANCE);
diff --git a/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java
index f417f5aa4c93..dc63784e19aa 100644
--- a/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java
+++ b/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java
@@ -49,7 +49,13 @@ public class PyCallableTypeImpl implements PyCallableType {
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
+ public PyType getReturnType(@NotNull TypeEvalContext context) {
+ return myReturnType;
+ }
+
+ @Nullable
+ @Override
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
return myReturnType;
}
@@ -105,7 +111,7 @@ public class PyCallableTypeImpl implements PyCallableType {
}
@Override
- public boolean isBuiltin(TypeEvalContext context) {
+ public boolean isBuiltin() {
return false;
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
index 715421ace1cb..778b8387f85e 100644
--- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
+++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
@@ -163,7 +163,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
}
}
- if ("super".equals(getClassQName()) && isBuiltin(context) && location instanceof PyCallExpression) {
+ if ("super".equals(getClassQName()) && isBuiltin() && location instanceof PyCallExpression) {
// methods of super() call are not of class super!
PyExpression first_arg = ((PyCallExpression)location).getArgument(0, PyExpression.class);
if (first_arg != null) { // the usual case: first arg is the derived class that super() is proxying for
@@ -307,7 +307,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
+ public PyType getReturnType(@NotNull TypeEvalContext context) {
if (isDefinition()) {
return new PyClassTypeImpl(getPyClass(), false);
}
@@ -316,6 +316,12 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
@Nullable
@Override
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ return getReturnType(context);
+ }
+
+ @Nullable
+ @Override
public List<PyCallableParameter> getParameters(@NotNull TypeEvalContext context) {
return null;
}
@@ -530,8 +536,8 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
}
@Override
- public boolean isBuiltin(TypeEvalContext context) {
- return PyBuiltinCache.getInstance(myClass).hasInBuiltins(myClass);
+ public boolean isBuiltin() {
+ return PyBuiltinCache.getInstance(myClass).isBuiltin(myClass);
}
@Override
diff --git a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java
index 5e0c35699067..229fe2677d12 100644
--- a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java
+++ b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java
@@ -46,8 +46,14 @@ public class PyFunctionType implements PyCallableType {
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
- return myCallable.getReturnType(context, callSite);
+ public PyType getReturnType(@NotNull TypeEvalContext context) {
+ return context.getReturnType(myCallable);
+ }
+
+ @Nullable
+ @Override
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ return myCallable.getCallType(context, callSite);
}
@Nullable
@@ -79,7 +85,7 @@ public class PyFunctionType implements PyCallableType {
}
@Override
- public boolean isBuiltin(TypeEvalContext context) {
+ public boolean isBuiltin() {
return false;
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyGenericType.java b/python/src/com/jetbrains/python/psi/types/PyGenericType.java
index af7aaae80c44..68256ae6c3f3 100644
--- a/python/src/com/jetbrains/python/psi/types/PyGenericType.java
+++ b/python/src/com/jetbrains/python/psi/types/PyGenericType.java
@@ -59,7 +59,7 @@ public class PyGenericType implements PyType {
}
@Override
- public boolean isBuiltin(TypeEvalContext context) {
+ public boolean isBuiltin() {
return false;
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java b/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java
index 3b56b6320289..5f66c818388d 100644
--- a/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java
+++ b/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java
@@ -90,7 +90,7 @@ public class PyImportedModuleType implements PyType {
}
@Override
- public boolean isBuiltin(TypeEvalContext context) {
+ public boolean isBuiltin() {
return false; // no module can be imported from builtins
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyModuleType.java b/python/src/com/jetbrains/python/psi/types/PyModuleType.java
index 5e495cdd4a88..f58f8f879c3b 100644
--- a/python/src/com/jetbrains/python/psi/types/PyModuleType.java
+++ b/python/src/com/jetbrains/python/psi/types/PyModuleType.java
@@ -407,7 +407,7 @@ public class PyModuleType implements PyType { // Modules don't descend from obje
}
@Override
- public boolean isBuiltin(TypeEvalContext context) {
+ public boolean isBuiltin() {
return true;
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyNoneType.java b/python/src/com/jetbrains/python/psi/types/PyNoneType.java
index 05a793182e57..417f0ce1a2f1 100644
--- a/python/src/com/jetbrains/python/psi/types/PyNoneType.java
+++ b/python/src/com/jetbrains/python/psi/types/PyNoneType.java
@@ -53,7 +53,7 @@ public class PyNoneType implements PyType { // TODO must extend ClassType. It's
}
@Override
- public boolean isBuiltin(TypeEvalContext context) {
+ public boolean isBuiltin() {
return true;
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyTupleType.java b/python/src/com/jetbrains/python/psi/types/PyTupleType.java
index 8ede14ea8c99..ae6ca00b3dbd 100644
--- a/python/src/com/jetbrains/python/psi/types/PyTupleType.java
+++ b/python/src/com/jetbrains/python/psi/types/PyTupleType.java
@@ -63,7 +63,7 @@ public class PyTupleType extends PyClassTypeImpl implements PySubscriptableType
}
@Override
- public boolean isBuiltin(TypeEvalContext context) {
+ public boolean isBuiltin() {
return true;
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
index 632633bc6501..cbdeb163e923 100644
--- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
+++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
@@ -20,7 +20,6 @@ import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.PsiReference;
import com.intellij.psi.ResolveResult;
import com.jetbrains.python.PyNames;
-import com.jetbrains.python.codeInsight.stdlib.PyStdlibTypeProvider;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
@@ -172,8 +171,7 @@ public class PyTypeChecker {
}
}
}
- if (!match(expectedCallable.getCallType(context, null), actualCallable.getCallType(context, null), context, substitutions,
- recursive)) {
+ if (!match(expectedCallable.getReturnType(context), actualCallable.getReturnType(context), context, substitutions, recursive)) {
return false;
}
return true;
@@ -259,7 +257,7 @@ public class PyTypeChecker {
}
}
}
- collectGenerics(callable.getCallType(context, null), context, collected, visited);
+ collectGenerics(callable.getReturnType(context), context, collected, visited);
}
}
@@ -309,7 +307,7 @@ public class PyTypeChecker {
substParams.add(subst);
}
}
- final PyType substResult = substitute(callable.getCallType(context, null), substitutions, context);
+ final PyType substResult = substitute(callable.getReturnType(context), substitutions, context);
return new PyCallableTypeImpl(substParams, substResult);
}
}
@@ -317,11 +315,10 @@ public class PyTypeChecker {
}
@Nullable
- public static Map<PyGenericType, PyType> unifyGenericCall(@NotNull PyFunction function,
- @Nullable PyExpression receiver,
+ public static Map<PyGenericType, PyType> unifyGenericCall(@Nullable PyExpression receiver,
@NotNull Map<PyExpression, PyNamedParameter> arguments,
@NotNull TypeEvalContext context) {
- final Map<PyGenericType, PyType> substitutions = collectCallGenerics(function, receiver, context);
+ final Map<PyGenericType, PyType> substitutions = unifyReceiver(receiver, context);
for (Map.Entry<PyExpression, PyNamedParameter> entry : arguments.entrySet()) {
final PyNamedParameter p = entry.getValue();
if (p.isPositionalContainer() || p.isKeywordContainer()) {
@@ -337,8 +334,7 @@ public class PyTypeChecker {
}
@NotNull
- public static Map<PyGenericType, PyType> collectCallGenerics(@NotNull Callable callable, @Nullable PyExpression receiver,
- @NotNull TypeEvalContext context) {
+ public static Map<PyGenericType, PyType> unifyReceiver(@Nullable PyExpression receiver, @NotNull TypeEvalContext context) {
final Map<PyGenericType, PyType> substitutions = new LinkedHashMap<PyGenericType, PyType>();
// Collect generic params of object type
final Set<PyGenericType> generics = new LinkedHashSet<PyGenericType>();
@@ -347,14 +343,22 @@ public class PyTypeChecker {
for (PyGenericType t : generics) {
substitutions.put(t, t);
}
- final PyClass cls = (callable instanceof PyFunction) ? ((PyFunction)callable).getContainingClass() : null;
- if (cls != null) {
- final PyFunction init = cls.findInitOrNew(true);
- // Unify generics in constructor
- if (init != null) {
- final PyType initType = init.getReturnType(context, null);
- if (initType != null) {
- match(initType, qualifierType, context, substitutions);
+ // Unify generics in constructor
+ if (qualifierType != null) {
+ final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
+ // TODO: Resolve to __new__ as well
+ final List<? extends RatedResolveResult> results = qualifierType.resolveMember(PyNames.INIT, null, AccessDirection.READ,
+ resolveContext);
+ if (results != null && !results.isEmpty()) {
+ final PsiElement init = results.get(0).getElement();
+ if (init instanceof PyTypedElement) {
+ final PyType initType = context.getType((PyTypedElement)init);
+ if (initType instanceof PyCallableType) {
+ final PyType initReturnType = ((PyCallableType)initType).getReturnType(context);
+ if (initReturnType != null) {
+ match(initReturnType, qualifierType, context, substitutions);
+ }
+ }
}
}
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyUnionType.java b/python/src/com/jetbrains/python/psi/types/PyUnionType.java
index abdc5ad34428..8572b72c1771 100644
--- a/python/src/com/jetbrains/python/psi/types/PyUnionType.java
+++ b/python/src/com/jetbrains/python/psi/types/PyUnionType.java
@@ -77,13 +77,12 @@ public class PyUnionType implements PyType {
}
/**
- * @param context
* @return true if all types in the union are built-in.
*/
@Override
- public boolean isBuiltin(TypeEvalContext context) {
+ public boolean isBuiltin() {
for (PyType one : myMembers) {
- if (one == null || !one.isBuiltin(context)) return false;
+ if (one == null || !one.isBuiltin()) return false;
}
return true;
}
diff --git a/python/src/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureHandler.java b/python/src/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureHandler.java
index 719bc833d1bf..6895249a641f 100644
--- a/python/src/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureHandler.java
+++ b/python/src/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureHandler.java
@@ -153,7 +153,7 @@ public class PyChangeSignatureHandler implements ChangeSignatureHandler {
final PyClass baseClass = deepestSuperMethod.getContainingClass();
final PyBuiltinCache cache = PyBuiltinCache.getInstance(baseClass);
String baseClassName = baseClass == null? "" : baseClass.getName();
- if (cache.hasInBuiltins(baseClass))
+ if (cache.isBuiltin(baseClass))
return function;
final String message = PyBundle.message(
"refactoring.change.signature.find.usages.of.base.class",
diff --git a/python/src/com/jetbrains/python/refactoring/classes/DependencyVisitor.java b/python/src/com/jetbrains/python/refactoring/classes/DependencyVisitor.java
index b22449d9abb0..6cb4504bb960 100644
--- a/python/src/com/jetbrains/python/refactoring/classes/DependencyVisitor.java
+++ b/python/src/com/jetbrains/python/refactoring/classes/DependencyVisitor.java
@@ -38,9 +38,24 @@ class DependencyVisitor extends PyRecursiveElementVisitor {
}
final String calleeName = callee.getName();
- if ((calleeName != null) && calleeName.equals(myElementToFind.getName())) { // Check by name also
+ final String name = myElementToFind.getName();
+ if ((calleeName != null) && calleeName.equals(name)) { // Check by name also
myDependencyFound = true;
}
+
+ // Member could be used as method param
+ final PyArgumentList list = node.getArgumentList();
+ if (list != null) {
+ for (final PyExpression expression : node.getArgumentList().getArgumentExpressions()) {
+ final PsiReference reference = expression.getReference();
+ if ((reference != null) && reference.isReferenceTo(myElementToFind)) {
+ myDependencyFound = true;
+ }
+ if ((name != null) && name.equals(expression.getName())) {
+ myDependencyFound = true;
+ }
+ }
+ }
}
}
diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java
index 79f0382a8e23..25b8a23703cf 100644
--- a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java
+++ b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java
@@ -125,7 +125,7 @@ public final class PyClassRefactoringUtil {
}
@NotNull
- public static List<PyFunction> copyMethods(Collection<PyFunction> methods, PyClass superClass) {
+ public static List<PyFunction> copyMethods(Collection<PyFunction> methods, PyClass superClass, boolean skipIfExist ) {
if (methods.isEmpty()) {
return Collections.emptyList();
}
@@ -133,7 +133,7 @@ public final class PyClassRefactoringUtil {
rememberNamedReferences(e);
}
final PyFunction[] elements = methods.toArray(new PyFunction[methods.size()]);
- return addMethods(superClass, true, elements);
+ return addMethods(superClass, skipIfExist, elements);
}
/**
@@ -298,7 +298,7 @@ public final class PyClassRefactoringUtil {
}
public static boolean insertImport(PsiElement anchor, PsiNamedElement element, @Nullable String asName, boolean preferFromImport) {
- if (PyBuiltinCache.getInstance(element).hasInBuiltins(element)) return false;
+ if (PyBuiltinCache.getInstance(element).isBuiltin(element)) return false;
final PsiFile newFile = element.getContainingFile();
final PsiFile file = anchor.getContainingFile();
if (newFile == file) return false;
diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java
index 3bf4f00553e1..281ad586bdd7 100644
--- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java
+++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java
@@ -1,9 +1,9 @@
package com.jetbrains.python.refactoring.classes.membersManager;
-import com.jetbrains.python.psi.PyAssignmentStatement;
-import com.jetbrains.python.psi.PyClass;
-import com.jetbrains.python.psi.PyElement;
-import com.jetbrains.python.psi.PyTargetExpression;
+import com.google.common.collect.FluentIterable;
+import com.jetbrains.NotNullPredicate;
+import com.jetbrains.python.PyNames;
+import com.jetbrains.python.psi.*;
import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil;
import org.jetbrains.annotations.NotNull;
@@ -31,8 +31,21 @@ class ClassFieldsManager extends FieldsManager {
protected Collection<PyElement> moveAssignments(@NotNull final PyClass from,
@NotNull final Collection<PyAssignmentStatement> statements,
@NotNull final PyClass... to) {
+ return moveAssignmentsImpl(from, statements, to);
+ }
+
+ /**
+ * Moves assignments from one class to anothers
+ * @param from source
+ * @param statements assignments
+ * @param to destination
+ * @return newly created assignments
+ */
+ static Collection<PyElement> moveAssignmentsImpl(@NotNull final PyClass from,
+ @NotNull final Collection<PyAssignmentStatement> statements,
+ @NotNull final PyClass... to) {
//TODO: Copy/paste with InstanceFieldsManager. Move to parent?
- final List<PyElement> result = new ArrayList<PyElement>();
+ final Collection<PyElement> result = new ArrayList<PyElement>();
for (final PyClass destClass : to) {
result.addAll(PyClassRefactoringUtil.copyFieldDeclarationToStatement(statements, destClass.getStatementList(), destClass));
}
@@ -49,6 +62,39 @@ class ClassFieldsManager extends FieldsManager {
@NotNull
@Override
protected List<PyTargetExpression> getFieldsByClass(@NotNull final PyClass pyClass) {
- return pyClass.getClassAttributes();
+ return FluentIterable.from(pyClass.getClassAttributes()).filter(new NoMetaAndProperties(pyClass)).toList();
+ }
+
+ /**
+ * Exclude "__metaclass__" field and properties (there should be separate managers for them)
+ * TODO: Check type and filter out any builtin element instead?
+ */
+ private static class NoMetaAndProperties extends NotNullPredicate<PyTargetExpression> {
+ @NotNull
+ private final PyClass myClass;
+
+ private NoMetaAndProperties(@NotNull final PyClass aClass) {
+ myClass = aClass;
+ }
+
+ @Override
+ public boolean applyNotNull(@NotNull final PyTargetExpression input) {
+ final String name = input.getName();
+ if (name == null) {
+ return false;
+ }
+ if (name.equals(PyNames.DUNDER_METACLASS)) {
+ return false;
+ }
+
+ final PyExpression assignedValue = input.findAssignedValue();
+ if (assignedValue instanceof PyCallExpression) {
+ final PyExpression callee = ((PyCallExpression)assignedValue).getCallee();
+ if ((callee != null) && PyNames.PROPERTY.equals(callee.getName()) && (myClass.findProperty(name, false) != null)) {
+ return false;
+ }
+ }
+ return true;
+ }
}
}
diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/FieldsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/FieldsManager.java
index cb15b2b561a4..5dd32888ec22 100644
--- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/FieldsManager.java
+++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/FieldsManager.java
@@ -43,9 +43,9 @@ abstract class FieldsManager extends MembersManager<PyTargetExpression> {
@NotNull
@Override
protected MultiMap<PyClass, PyElement> getDependencies(@NotNull final PyElement member) {
- final MultiMap<PyClass, PyElement> result = new MultiMap<PyClass, PyElement>();
- member.accept(new MyPyRecursiveElementVisitor(result));
- return result;
+ final PyRecursiveElementVisitorWithResult visitor = new MyPyRecursiveElementVisitor();
+ member.accept(visitor);
+ return visitor.myResult;
}
@Override
@@ -89,7 +89,7 @@ abstract class FieldsManager extends MembersManager<PyTargetExpression> {
* @return list of fields in target expression (declaration) form
*/
@NotNull
- protected abstract List<PyTargetExpression> getFieldsByClass(@NotNull PyClass pyClass);
+ protected abstract Collection<PyTargetExpression> getFieldsByClass(@NotNull PyClass pyClass);
@NotNull
@@ -135,13 +135,7 @@ abstract class FieldsManager extends MembersManager<PyTargetExpression> {
/**
* Fetches field declarations
*/
- private static class MyPyRecursiveElementVisitor extends PyRecursiveElementVisitor {
- @NotNull
- private final MultiMap<PyClass, PyElement> myResult;
-
- private MyPyRecursiveElementVisitor(@NotNull final MultiMap<PyClass, PyElement> result) {
- myResult = result;
- }
+ private static class MyPyRecursiveElementVisitor extends PyRecursiveElementVisitorWithResult {
@Override
public void visitPyReferenceExpression(final PyReferenceExpression node) {
diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/InstanceFieldsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/InstanceFieldsManager.java
index a1e19c455a0f..357d9e896c00 100644
--- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/InstanceFieldsManager.java
+++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/InstanceFieldsManager.java
@@ -8,7 +8,6 @@ import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyFunctionBuilder;
import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
@@ -18,6 +17,7 @@ import java.util.List;
* @author Ilya.Kazakevich
*/
class InstanceFieldsManager extends FieldsManager {
+ private static final FieldsOnly FIELDS_ONLY = new FieldsOnly();
// PY-12170
@@ -92,8 +92,8 @@ class InstanceFieldsManager extends FieldsManager {
@NotNull
@Override
- protected List<PyTargetExpression> getFieldsByClass(@NotNull final PyClass pyClass) {
- return pyClass.getInstanceAttributes();
+ protected Collection<PyTargetExpression> getFieldsByClass(@NotNull final PyClass pyClass) {
+ return Collections2.filter(pyClass.getInstanceAttributes(), FIELDS_ONLY);
}
private static class InitsOnly extends NotNullPredicate<PyAssignmentStatement> {
@@ -115,4 +115,11 @@ class InstanceFieldsManager extends FieldsManager {
return myInitMethod.equals(functionWhereDeclared);
}
}
+
+ private static class FieldsOnly extends NotNullPredicate<PyTargetExpression> {
+ @Override
+ protected boolean applyNotNull(@NotNull final PyTargetExpression input) {
+ return input.getReference().resolve() instanceof PyTargetExpression;
+ }
+ }
}
diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java
index 437b8085d765..b2d8dac2c4a8 100644
--- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java
+++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java
@@ -20,7 +20,6 @@ import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiNamedElement;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.MultiMap;
import com.jetbrains.NotNullPredicate;
@@ -45,7 +44,11 @@ public abstract class MembersManager<T extends PyElement> implements Function<T,
* List of managers. Class delegates all logic to them.
*/
private static final Collection<? extends MembersManager<? extends PyElement>> MANAGERS =
- Arrays.asList(new MethodsManager(), new SuperClassesManager(), new ClassFieldsManager(), new InstanceFieldsManager());
+ Arrays.asList(new MethodsManager(),
+ new SuperClassesManager(),
+ new ClassFieldsManager(),
+ new InstanceFieldsManager(),
+ new PropertiesManager());
@NotNull
private final Class<T> myExpectedClass;
@@ -84,7 +87,7 @@ public abstract class MembersManager<T extends PyElement> implements Function<T,
@SuppressWarnings({"unchecked", "rawtypes"}) //We check type at runtime
private static Collection<PyMemberInfo<PyElement>> transformSafely(@NotNull final PyClass pyClass,
@NotNull final MembersManager<?> manager) {
- final List<PyElement> membersCouldBeMoved = manager.getMembersCouldBeMoved(pyClass);
+ final List<? extends PyElement> membersCouldBeMoved = manager.getMembersCouldBeMoved(pyClass);
manager.checkElementTypes((Iterable)membersCouldBeMoved);
return (Collection<PyMemberInfo<PyElement>>)Collections2.transform(membersCouldBeMoved, (Function)manager);
}
@@ -175,7 +178,8 @@ public abstract class MembersManager<T extends PyElement> implements Function<T,
/**
* Finds member in class.
- * @param pyClass class to find member in
+ *
+ * @param pyClass class to find member in
* @param pyElement element to find
* @return member info with element
*/
@@ -195,25 +199,10 @@ public abstract class MembersManager<T extends PyElement> implements Function<T,
* @return list of members
*/
@NotNull
- protected abstract List<PyElement> getMembersCouldBeMoved(@NotNull PyClass pyClass);
+ protected abstract List<? extends PyElement> getMembersCouldBeMoved(@NotNull PyClass pyClass);
/**
- * Filters out named elements (ones that subclasses {@link com.intellij.psi.PsiNamedElement}) and {@link com.jetbrains.python.psi.PyElement})
- * that are null or has null name.
- * You need it sometimes when code has errors (i.e. bad formatted code with annotation may treat annotation as method with null name.
- * note: we should probably throw exceptions in such cases and display "refactoring not available" window in handler)
- *
- * @param elementsToFilter collection of elements to filter
- * @param <T> element type
- * @return collection of T with out of nulls and elemens whos {@link com.intellij.psi.PsiNamedElement#getName()} returns null
- */
- @NotNull
- protected static <T extends PsiNamedElement & PyElement> Collection<T> filterNameless(@NotNull final Collection<T> elementsToFilter) {
- return Collections2.filter(elementsToFilter, new NamelessFilter<T>());
- }
-
- /**
* Returns list of elements that may require reference storing aid from {@link com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil#rememberNamedReferences(com.intellij.psi.PsiElement, String...)}
*
* @param elements members chosen by user. In most cases members their selves could be stored, but different managers may support other strategies
@@ -227,6 +216,7 @@ public abstract class MembersManager<T extends PyElement> implements Function<T,
/**
* Moves element from one class to another. Returns members that may require reference restoring aid from
* ({@link com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil#restoreNamedReferences(com.intellij.psi.PsiElement)})
+ * Sort members according to their dependncies, before calling this method
*
* @see #getElementsToStoreReferences(java.util.Collection)
*/
@@ -357,13 +347,6 @@ public abstract class MembersManager<T extends PyElement> implements Function<T,
}
}
- private static class NamelessFilter<T extends PyElement & PsiNamedElement> extends NotNullPredicate<T> {
- @Override
- public boolean applyNotNull(@NotNull final T input) {
- return input.getName() != null;
- }
- }
-
private static class FindByElement extends NotNullPredicate<PyMemberInfo<PyElement>> {
private final PyElement myPyElement;
diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java
index 7cba0a2a639c..52c32d95d38d 100644
--- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java
+++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java
@@ -1,7 +1,8 @@
package com.jetbrains.python.refactoring.classes.membersManager;
+import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
+import com.google.common.collect.FluentIterable;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -35,6 +36,7 @@ class MethodsManager extends MembersManager<PyFunction> {
{PyNames.PROPERTY, PyNames.CLASSMETHOD, PyNames.STATICMETHOD};
public static final String ABC_META_PACKAGE = "abc";
+ private static final NoPropertiesPredicate NO_PROPERTIES = new NoPropertiesPredicate();
MethodsManager() {
super(PyFunction.class);
@@ -54,16 +56,15 @@ class MethodsManager extends MembersManager<PyFunction> {
@NotNull
@Override
protected MultiMap<PyClass, PyElement> getDependencies(@NotNull final PyElement member) {
- final MultiMap<PyClass, PyElement> result = new MultiMap<PyClass, PyElement>();
- member.accept(new MyPyRecursiveElementVisitor(result));
-
- return result;
+ final MyPyRecursiveElementVisitor visitor = new MyPyRecursiveElementVisitor();
+ member.accept(visitor);
+ return visitor.myResult;
}
@NotNull
@Override
- protected List<PyElement> getMembersCouldBeMoved(@NotNull final PyClass pyClass) {
- return Lists.<PyElement>newArrayList(filterNameless(Arrays.asList(pyClass.getMethods())));
+ protected List<? extends PyElement> getMembersCouldBeMoved(@NotNull final PyClass pyClass) {
+ return FluentIterable.from(Arrays.asList(pyClass.getMethods())).filter(new NamelessFilter<PyFunction>()).filter(NO_PROPERTIES).toList();
}
@Override
@@ -74,7 +75,7 @@ class MethodsManager extends MembersManager<PyFunction> {
final Collection<PyFunction> methodsToAbstract = fetchElements(Collections2.filter(members, new AbstractFilter(true)));
makeMethodsAbstract(methodsToAbstract, to);
- return moveMethods(from, methodsToMove, to);
+ return moveMethods(from, methodsToMove, true, to);
}
/**
@@ -156,9 +157,10 @@ class MethodsManager extends MembersManager<PyFunction> {
* @param from source
* @param methodsToMove what to move
* @param to where
+ * @param skipIfExist skip (do not add) if method already exists
* @return newly added methods
*/
- private static List<PyElement> moveMethods(final PyClass from, final Collection<PyFunction> methodsToMove, final PyClass... to) {
+ static List<PyElement> moveMethods(final PyClass from, final Collection<PyFunction> methodsToMove, final boolean skipIfExist, final PyClass... to) {
final List<PyElement> result = new ArrayList<PyElement>();
for (final PyClass destClass : to) {
//We move copies here because there may be several destinations
@@ -168,7 +170,7 @@ class MethodsManager extends MembersManager<PyFunction> {
copies.add(newMethod);
}
- result.addAll(PyClassRefactoringUtil.copyMethods(copies, destClass));
+ result.addAll(PyClassRefactoringUtil.copyMethods(copies, destClass, skipIfExist));
}
deleteElements(methodsToMove);
@@ -251,14 +253,7 @@ class MethodsManager extends MembersManager<PyFunction> {
}
}
- private static class MyPyRecursiveElementVisitor extends PyRecursiveElementVisitor {
- @NotNull
- private final MultiMap<PyClass, PyElement> myResult;
-
- private MyPyRecursiveElementVisitor(@NotNull final MultiMap<PyClass, PyElement> result) {
- myResult = result;
- }
-
+ private static class MyPyRecursiveElementVisitor extends PyRecursiveElementVisitorWithResult {
@Override
public void visitPyCallExpression(final PyCallExpression node) {
// TODO: refactor, messy code
@@ -281,4 +276,14 @@ class MethodsManager extends MembersManager<PyFunction> {
}
}
}
+
+ /**
+ * Filter out property setters and getters
+ */
+ private static class NoPropertiesPredicate implements Predicate<PyFunction> {
+ @Override
+ public boolean apply(@NotNull PyFunction input) {
+ return input.getProperty() == null;
+ }
+ }
}
diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/NamelessFilter.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/NamelessFilter.java
new file mode 100644
index 000000000000..ec688e3f4a9c
--- /dev/null
+++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/NamelessFilter.java
@@ -0,0 +1,21 @@
+package com.jetbrains.python.refactoring.classes.membersManager;
+
+import com.intellij.psi.PsiNamedElement;
+import com.jetbrains.NotNullPredicate;
+import com.jetbrains.python.psi.PyElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Filters out named elements (ones that subclasses {@link com.intellij.psi.PsiNamedElement}) and {@link com.jetbrains.python.psi.PyElement})
+ * that are null or has null name.
+ * You need it sometimes when code has errors (i.e. bad formatted code with annotation may treat annotation as method with null name.
+ *
+* @author Ilya.Kazakevich
+*/
+class NamelessFilter<T extends PyElement & PsiNamedElement> extends NotNullPredicate<T> {
+
+ @Override
+ public boolean applyNotNull(@NotNull final T input) {
+ return input.getName() != null;
+ }
+}
diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/PropertiesManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PropertiesManager.java
new file mode 100644
index 000000000000..142bb31e96d9
--- /dev/null
+++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PropertiesManager.java
@@ -0,0 +1,210 @@
+package com.jetbrains.python.refactoring.classes.membersManager;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.containers.MultiMap;
+import com.jetbrains.python.psi.*;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Plugin that moves class properties.
+ * It represents property (whatever old or new) as one of its methods.
+ *
+ * @author Ilya.Kazakevich
+ */
+class PropertiesManager extends MembersManager<PyElement> {
+
+ PropertiesManager() {
+ super(PyElement.class);
+ }
+
+
+ @NotNull
+ @Override
+ protected List<? extends PyElement> getMembersCouldBeMoved(@NotNull final PyClass pyClass) {
+ final List<PyElement> elements = new ArrayList<PyElement>(pyClass.getProperties().size());
+ for (final Property property : pyClass.getProperties().values()) {
+ elements.add(getElement(property));
+ }
+ return elements;
+ }
+
+ @NotNull
+ private static PyElement getElement(@NotNull final Property property) {
+ final Callable getter = property.getGetter().valueOrNull();
+ final Callable setter = property.getSetter().valueOrNull();
+ final Callable deleter = property.getDeleter().valueOrNull();
+
+ if (getter != null) {
+ return getter;
+ }
+ else if (setter != null) {
+ return setter;
+ }
+ else if (deleter != null) {
+ return deleter;
+ }
+ else {
+ final PyTargetExpression site = property.getDefinitionSite();
+ assert site != null : "Property has no methods nor declaration. That is not property";
+ return site;
+ }
+ }
+
+ @NotNull
+ private static Property getProperty(@NotNull final PyClass pyClass, @NotNull final PyElement element) {
+ final Collection<Property> properties = pyClass.getProperties().values();
+ if (element instanceof PyTargetExpression) {
+ return getPropertyByTargetExpression(properties, (PyTargetExpression)element);
+ }
+ if (element instanceof PyFunction) {
+ return getPropertyByFunction(properties, (PyFunction)element);
+ }
+ throw new IllegalArgumentException("Not function nor target");
+ }
+
+ @NotNull
+ private static Property getPropertyByFunction(@NotNull final Collection<Property> properties,
+ @NotNull final PyFunction functionToSearch) {
+ for (final Property property : properties) {
+ for (final PyFunction function : getAllFunctions(property)) {
+ if (function.equals(functionToSearch)) {
+ return property;
+ }
+ }
+ }
+ throw new IllegalArgumentException("No property found");
+ }
+
+ @NotNull
+ private static Property getPropertyByTargetExpression(@NotNull final Iterable<Property> properties,
+ @NotNull final PyTargetExpression element) {
+ for (final Property property : properties) {
+ if (element.equals(property.getDefinitionSite())) {
+ return property;
+ }
+ }
+ throw new IllegalArgumentException("No property found");
+ }
+
+ @NotNull
+ private static Collection<PyFunction> getAllFunctions(@NotNull final Property property) {
+ final Collection<PyFunction> result = new ArrayList<PyFunction>(3);
+ final Callable getter = property.getGetter().valueOrNull();
+ final Callable setter = property.getSetter().valueOrNull();
+ final Callable deleter = property.getDeleter().valueOrNull();
+
+ if (getter instanceof PyFunction) {
+ result.add((PyFunction)getter);
+ }
+ if (setter instanceof PyFunction) {
+ result.add((PyFunction)setter);
+ }
+ if (deleter instanceof PyFunction) {
+ result.add((PyFunction)deleter);
+ }
+ return result;
+ }
+
+ @Override
+ protected Collection<PyElement> moveMembers(@NotNull final PyClass from,
+ @NotNull final Collection<PyMemberInfo<PyElement>> members,
+ @NotNull final PyClass... to) {
+ final Collection<PyElement> result = new ArrayList<PyElement>();
+
+ final Collection<PyElement> elements = fetchElements(members);
+ for (final PyElement element : elements) {
+ final Property property = getProperty(from, element);
+ final Collection<PyFunction> functions = getAllFunctions(property);
+ MethodsManager.moveMethods(from, functions, false, to);
+ final PyTargetExpression definitionSite = property.getDefinitionSite();
+ if (definitionSite != null) {
+ final PyAssignmentStatement assignmentStatement = PsiTreeUtil.getParentOfType(definitionSite, PyAssignmentStatement.class);
+ ClassFieldsManager.moveAssignmentsImpl(from, Collections.singleton(assignmentStatement), to);
+ }
+ }
+ return result;
+ }
+
+ @NotNull
+ @Override
+ public PyMemberInfo<PyElement> apply(@NotNull final PyElement input) {
+ return new PyMemberInfo<PyElement>(input, false, getName(input), false, this, false);
+ }
+
+ private static String getName(@NotNull final PyElement input) {
+ final PyClass clazz = PsiTreeUtil.getParentOfType(input, PyClass.class);
+ assert clazz != null : "Element not declared in class";
+ final Property property = getProperty(clazz, input);
+ return property.getName();
+ }
+
+ @Override
+ public boolean hasConflict(@NotNull final PyElement member, @NotNull final PyClass aClass) {
+ return false;
+ }
+
+ @NotNull
+ @Override
+ protected MultiMap<PyClass, PyElement> getDependencies(@NotNull final PyElement member) {
+ final PyRecursiveElementVisitorWithResult visitor = new PyReferenceVisitor();
+ member.accept(visitor);
+
+ return visitor.myResult;
+ }
+
+ @NotNull
+ @Override
+ protected Collection<PyElement> getDependencies(@NotNull final MultiMap<PyClass, PyElement> usedElements) {
+ return Collections.emptyList();
+ }
+
+ private static class PyReferenceVisitor extends PyRecursiveElementVisitorWithResult {
+
+
+ @Override
+ public void visitPyExpression(final PyExpression node) {
+ final PsiReference reference = node.getReference();
+ if (reference == null) {
+ return;
+ }
+
+ final PsiElement declaration = reference.resolve();
+ if (!(declaration instanceof PyFunction)) {
+ return;
+ }
+
+ final PyFunction function = (PyFunction)declaration;
+ final Property property = function.getProperty();
+ if (property == null) {
+ return;
+ }
+
+ final PyClass aClass = function.getContainingClass();
+ if (aClass == null) {
+ return;
+ }
+ final Collection<PyFunction> functions = getAllFunctions(property);
+ for (final PyFunction pyFunction : functions) {
+ final PyClass functionClass = pyFunction.getContainingClass();
+ if (functionClass != null) {
+ myResult.putValue(functionClass, pyFunction);
+ }
+ }
+
+ final PyTargetExpression definitionSite = property.getDefinitionSite();
+ if (definitionSite != null) {
+ final PyClass pyClass = PsiTreeUtil.getParentOfType(definitionSite, PyClass.class);
+ if (pyClass != null) {
+ myResult.putValue(pyClass, definitionSite);
+ }
+ }
+ }
+ }
+}
diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyRecursiveElementVisitorWithResult.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyRecursiveElementVisitorWithResult.java
new file mode 100644
index 000000000000..14ba3aee84b2
--- /dev/null
+++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyRecursiveElementVisitorWithResult.java
@@ -0,0 +1,19 @@
+package com.jetbrains.python.refactoring.classes.membersManager;
+
+import com.intellij.util.containers.MultiMap;
+import com.jetbrains.python.psi.PyClass;
+import com.jetbrains.python.psi.PyElement;
+import com.jetbrains.python.psi.PyRecursiveElementVisitor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Recursive visitor with multimap, to be used for {@link com.jetbrains.python.refactoring.classes.membersManager.MembersManager#getDependencies(com.jetbrains.python.psi.PyElement)}
+ */
+class PyRecursiveElementVisitorWithResult extends PyRecursiveElementVisitor {
+ @NotNull
+ protected final MultiMap<PyClass, PyElement> myResult;
+
+ PyRecursiveElementVisitorWithResult() {
+ myResult = new MultiMap<PyClass, PyElement>();
+ }
+}
diff --git a/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java b/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java
index 7f774010aa8f..f479d104765e 100644
--- a/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java
+++ b/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java
@@ -207,7 +207,7 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
if (type != null && type != PyNoneType.INSTANCE) {
String typeName = type.getName();
if (typeName != null) {
- if (type.isBuiltin(context)) {
+ if (type.isBuiltin()) {
typeName = typeName.substring(0, 1);
}
candidates.addAll(NameSuggesterUtil.generateNamesByType(typeName));
diff --git a/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java b/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java
index deb8030f93c7..66cceb192a04 100644
--- a/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java
+++ b/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java
@@ -15,10 +15,10 @@
*/
package com.jetbrains.python.remote;
-import com.intellij.remotesdk2.RemoteSdkAdditionalData2;
+import com.intellij.remote.RemoteSdkAdditionalData;
/**
* @author traff
*/
-public interface PyRemoteSdkAdditionalDataBase extends RemoteSdkAdditionalData2<PyRemoteSdkCredentials>, PySkeletonsPathAware {
+public interface PyRemoteSdkAdditionalDataBase extends RemoteSdkAdditionalData<PyRemoteSdkCredentials>, PySkeletonsPathAware {
}
diff --git a/python/src/com/jetbrains/python/remote/PyRemoteSdkCredentials.java b/python/src/com/jetbrains/python/remote/PyRemoteSdkCredentials.java
index 5b5fc9b9e7e3..d9a9f04ecce2 100644
--- a/python/src/com/jetbrains/python/remote/PyRemoteSdkCredentials.java
+++ b/python/src/com/jetbrains/python/remote/PyRemoteSdkCredentials.java
@@ -15,7 +15,7 @@
*/
package com.jetbrains.python.remote;
-import com.intellij.remotesdk.RemoteSdkCredentials;
+import com.intellij.remote.RemoteSdkCredentials;
/**
* @author yole
diff --git a/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java b/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java
index 40e34f174acc..4276ed8cafe5 100644
--- a/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java
+++ b/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java
@@ -27,9 +27,8 @@ import com.intellij.openapi.projectRoots.SdkAdditionalData;
import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.remotesdk.RemoteInterpreterException;
-import com.intellij.remotesdk.RemoteSdkCredentials;
-import com.intellij.remotesdk.RemoteSshProcess;
+import com.intellij.remote.*;
+import com.intellij.remote.RemoteSdkException;
import com.intellij.util.NullableConsumer;
import com.intellij.util.PathMappingSettings;
import com.jetbrains.python.PythonHelpersLocator;
@@ -49,21 +48,21 @@ public abstract class PythonRemoteInterpreterManager {
public final static ExtensionPointName<PythonRemoteInterpreterManager> EP_NAME =
ExtensionPointName.create("Pythonid.remoteInterpreterManager");
public static final String WEB_DEPLOYMENT_PLUGIN_IS_DISABLED =
- "Remote interpreter can't be executed. Please enable the Remote Hosts Access plugin.";
+ "Remote interpreter can't be executed. Please enable the Remote Hosts Access plugin."; //TODO: this message is incorrect
public abstract ProcessHandler startRemoteProcess(@Nullable Project project,
@NotNull PyRemoteSdkCredentials data,
@NotNull GeneralCommandLine commandLine,
@Nullable
PathMappingSettings mappingSettings)
- throws RemoteInterpreterException;
+ throws RemoteSdkException;
public abstract ProcessHandler startRemoteProcessWithPid(@Nullable Project project,
@NotNull PyRemoteSdkCredentials data,
@NotNull GeneralCommandLine commandLine,
@Nullable
PathMappingSettings mappingSettings)
- throws RemoteInterpreterException;
+ throws RemoteSdkException;
public abstract void addRemoteSdk(Project project, Component parentComponent, Collection<Sdk> existingSdks,
NullableConsumer<Sdk> sdkCallback);
@@ -74,13 +73,13 @@ public abstract class PythonRemoteInterpreterManager {
String[] command,
@Nullable String workingDir,
boolean askForSudo)
- throws RemoteInterpreterException;
+ throws RemoteSdkException;
@NotNull
public abstract RemoteSshProcess createRemoteProcess(@Nullable Project project,
@NotNull RemoteSdkCredentials data,
@NotNull GeneralCommandLine commandLine, boolean allocatePty)
- throws RemoteInterpreterException;
+ throws RemoteSdkException;
public abstract boolean editSdk(@NotNull Project project, @NotNull SdkModificator sdkModificator, Collection<Sdk> existingSdks);
@@ -140,6 +139,8 @@ public abstract class PythonRemoteInterpreterManager {
public abstract SdkAdditionalData loadRemoteSdkData(Sdk sdk, Element additional);
+ public abstract boolean testConnection(RemoteCredentials credentials);
+
public static class PyRemoteInterpreterExecutionException extends ExecutionException {
public PyRemoteInterpreterExecutionException() {
@@ -153,5 +154,11 @@ public abstract class PythonRemoteInterpreterManager {
super(WEB_DEPLOYMENT_PLUGIN_IS_DISABLED);
}
}
+
+ public abstract RemoteCredentials getVagrantRemoteCredentials(VagrantBasedCredentialsHolder data);
+
+ public abstract void checkVagrantStatus(VagrantBasedCredentialsHolder data);
+
+ public abstract RemoteCredentials getCredentialsBySftpServerId(String id);
}
diff --git a/python/src/com/jetbrains/python/remote/RemoteDebuggableProcessHandler.java b/python/src/com/jetbrains/python/remote/RemoteDebuggableProcessHandler.java
index 514fc2a59d8e..db2b329e1fd7 100644
--- a/python/src/com/jetbrains/python/remote/RemoteDebuggableProcessHandler.java
+++ b/python/src/com/jetbrains/python/remote/RemoteDebuggableProcessHandler.java
@@ -15,7 +15,7 @@
*/
package com.jetbrains.python.remote;
-import com.intellij.remotesdk.RemoteProcessHandlerBase;
+import com.intellij.remote.RemoteProcessHandlerBase;
import com.jetbrains.python.debugger.PyDebugProcess;
import com.jetbrains.python.debugger.PyPositionConverter;
diff --git a/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java b/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java
index 5941d5f345c9..673b87dfd53d 100644
--- a/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java
+++ b/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java
@@ -24,10 +24,8 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkAdditionalData;
-import com.intellij.remotesdk2.RemoteSdkAdditionalData2;
import com.intellij.util.PathMappingSettings;
import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase;
-import com.jetbrains.python.remote.PyRemoteSdkCredentials;
import com.jetbrains.python.remote.PythonRemoteInterpreterManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.form b/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.form
deleted file mode 100644
index ea6172e1faac..000000000000
--- a/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.form
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.python.sdk.CreateVirtualEnvDialog">
- <grid id="cbd77" binding="myMainPanel" 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>
- <xy x="48" y="54" width="550" height="342"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children>
- <component id="23a50" class="javax.swing.JComboBox" binding="mySdkCombo">
- <constraints>
- <grid row="2" 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>
- <vspacer id="b277d">
- <constraints>
- <grid row="5" 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>
- <component id="48fd" class="com.intellij.ui.components.JBLabel">
- <constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text value="&amp;Base interpreter:"/>
- </properties>
- </component>
- <component id="a1259" class="javax.swing.JTextField" binding="myName">
- <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="29c55" class="com.intellij.ui.components.JBLabel">
- <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>
- <labelFor value="a1259"/>
- <text value="&amp;Name:"/>
- </properties>
- </component>
- <component id="1b80c" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myDestination">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties/>
- </component>
- <component id="42f44" class="com.intellij.ui.components.JBLabel">
- <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="&amp;Location:"/>
- </properties>
- </component>
- <component id="41e08" class="com.intellij.ui.components.JBCheckBox" binding="myMakeAvailableToAllProjectsCheckbox">
- <constraints>
- <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <selected value="false"/>
- <text value="Make available to &amp;all projects"/>
- </properties>
- </component>
- <component id="d10a9" class="com.intellij.ui.components.JBCheckBox" binding="mySitePackagesCheckBox">
- <constraints>
- <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <selected value="false"/>
- <text value="&amp;Inherit global site-packages"/>
- </properties>
- </component>
- </children>
- </grid>
-</form>
diff --git a/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java b/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java
index 104386625e07..e2cfe9c36914 100644
--- a/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java
+++ b/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java
@@ -29,16 +29,21 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl;
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil;
+import com.intellij.openapi.ui.ComboBox;
+import com.intellij.openapi.ui.FixedSizeButton;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
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.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.platform.LocationNameFieldsBinding;
-import com.intellij.remotesdk.RemoteSdkCredentialsHolder;
+import com.intellij.remote.RemoteSdkCredentialsHolder;
import com.intellij.ui.CollectionComboBoxModel;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.components.JBCheckBox;
+import com.intellij.ui.components.JBLabel;
+import com.intellij.util.NullableConsumer;
import com.intellij.util.PathUtil;
import com.intellij.util.PlatformUtils;
import com.jetbrains.python.packaging.PyExternalProcessException;
@@ -91,7 +96,7 @@ public class CreateVirtualEnvDialog extends IdeaDialog {
final String name =
SdkConfigurationUtil.createUniqueSdkName(PythonSdkType.getInstance(), sdkHome.getPath(), allSdks);
final ProjectJdkImpl sdk = new ProjectJdkImpl(name, PythonSdkType.getInstance());
- sdk.setHomePath(sdkHome.getPath());
+ sdk.setHomePath(FileUtil.toSystemDependentName(sdkHome.getPath()));
callback.virtualEnvCreated(sdk, associateWithProject);
PythonSdkType.setupSdkPaths(sdk, myProject, null);
}
@@ -111,17 +116,19 @@ public class CreateVirtualEnvDialog extends IdeaDialog {
setupDialog(null, allSdks, suggestedBaseSdk);
}
- private void setupDialog(Project project, List<Sdk> allSdks, @Nullable Sdk suggestedBaseSdk) {
+ private void setupDialog(Project project, final List<Sdk> allSdks, @Nullable Sdk suggestedBaseSdk) {
myProject = project;
+ layoutPanel(allSdks);
+
init();
setTitle("Create Virtual Environment");
+ Iterables.removeIf(allSdks, new Predicate<Sdk>() {
+ @Override
+ public boolean apply(Sdk s) {
+ return PythonSdkType.isInvalid(s) || PythonSdkType.isVirtualEnv(s) || RemoteSdkCredentialsHolder.isRemoteSdk(s.getHomePath());
+ }
+ });
if (suggestedBaseSdk == null && allSdks.size() > 0) {
- Iterables.removeIf(allSdks, new Predicate<Sdk>() {
- @Override
- public boolean apply(Sdk s) {
- return PythonSdkType.isInvalid(s) || PythonSdkType.isVirtualEnv(s) || RemoteSdkCredentialsHolder.isRemoteSdk(s.getHomePath());
- }
- });
List<Sdk> sortedSdks = new ArrayList<Sdk>(allSdks);
Collections.sort(sortedSdks, new PreferredSdkComparator());
suggestedBaseSdk = sortedSdks.get(0);
@@ -139,16 +146,19 @@ public class CreateVirtualEnvDialog extends IdeaDialog {
final VirtualFile file = VirtualEnvSdkFlavor.getDefaultLocation();
- if (file != null)
+ if (file != null) {
myInitialPath = file.getPath();
+ }
else {
final String savedPath = PyPackageService.getInstance().getVirtualEnvBasePath();
- if (!StringUtil.isEmptyOrSpaces(savedPath))
+ if (!StringUtil.isEmptyOrSpaces(savedPath)) {
myInitialPath = savedPath;
+ }
else if (myProject != null) {
final VirtualFile baseDir = myProject.getBaseDir();
- if (baseDir != null)
+ if (baseDir != null) {
myInitialPath = baseDir.getPath();
+ }
}
}
@@ -167,6 +177,87 @@ public class CreateVirtualEnvDialog extends IdeaDialog {
checkValid();
}
+ private void layoutPanel(final List<Sdk> allSdks) {
+ final GridBagLayout layout = new GridBagLayout();
+ myMainPanel = new JPanel(layout);
+
+ final GridBagConstraints c = new GridBagConstraints();
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.insets = new Insets(2,2,2,2);
+
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 0.0;
+ myMainPanel.add(new JBLabel("Name:"), c);
+
+ c.gridx = 1;
+ c.gridy = 0;
+ c.gridwidth = 2;
+ c.weightx = 1.0;
+ myName = new JTextField();
+ myMainPanel.add(myName, c);
+
+ c.gridx = 0;
+ c.gridy = 1;
+ c.gridwidth = 1;
+ c.weightx = 0.0;
+ myMainPanel.add(new JBLabel("Location:"), c);
+
+ c.gridx = 1;
+ c.gridy = 1;
+ c.gridwidth = 2;
+ c.weightx = 1.0;
+ myDestination = new TextFieldWithBrowseButton();
+ myMainPanel.add(myDestination, c);
+
+ c.gridx = 0;
+ c.gridy = 2;
+ c.gridwidth = 1;
+ c.weightx = 0.0;
+ myMainPanel.add(new JBLabel("Base interpreter:"), c);
+
+ c.gridx = 1;
+ c.gridy = 2;
+ mySdkCombo = new ComboBox();
+ c.insets = new Insets(2,2,2,2);
+ c.weightx = 1.0;
+ myMainPanel.add(mySdkCombo, c);
+
+ c.gridx = 2;
+ c.gridy = 2;
+ c.insets = new Insets(0,0,2,2);
+ c.weightx = 0.0;
+ FixedSizeButton button = new FixedSizeButton();
+ button.setPreferredSize(myDestination.getButton().getPreferredSize());
+ myMainPanel.add(button, c);
+
+ c.gridx = 0;
+ c.gridy = 3;
+ c.gridwidth = 3;
+ c.insets = new Insets(2,2,2,2);
+ mySitePackagesCheckBox = new JBCheckBox("Inherit global site-packages");
+ myMainPanel.add(mySitePackagesCheckBox, c);
+
+ c.gridx = 0;
+ c.gridy = 4;
+ myMakeAvailableToAllProjectsCheckbox = new JBCheckBox("Make available to all projects");
+ myMainPanel.add(myMakeAvailableToAllProjectsCheckbox, c);
+ button.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SdkConfigurationUtil.createSdk(myProject, allSdks.toArray(new Sdk[allSdks.size() - 1]), new NullableConsumer<Sdk>() {
+ @Override
+ public void consume(@Nullable Sdk sdk) {
+ if (sdk == null) return;
+ if (!allSdks.contains(sdk)) {
+ allSdks.add(sdk);
+ }
+ updateSdkList(allSdks, sdk);
+ }
+ }, false, PythonSdkType.getInstance());
+ }
+ });
+ }
+
private void checkValid() {
final String projectName = myName.getText();
if (new File(getDestination()).exists()) {
diff --git a/python/src/com/jetbrains/python/sdk/PySdkUtil.java b/python/src/com/jetbrains/python/sdk/PySdkUtil.java
index 4185da7fd42c..d8a2c2f6d0a3 100644
--- a/python/src/com/jetbrains/python/sdk/PySdkUtil.java
+++ b/python/src/com/jetbrains/python/sdk/PySdkUtil.java
@@ -25,8 +25,7 @@ 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.remotesdk.RemoteCredentials;
-import com.intellij.remotesdk2.RemoteSdkAdditionalData2;
+import com.intellij.remote.RemoteSdkAdditionalData;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
@@ -214,7 +213,7 @@ public class PySdkUtil {
}
public static boolean isRemote(@Nullable Sdk sdk) {
- return sdk != null && sdk.getSdkAdditionalData() instanceof RemoteSdkAdditionalData2;
+ return sdk != null && sdk.getSdkAdditionalData() instanceof RemoteSdkAdditionalData;
}
public static boolean isElementInSkeletons(@NotNull final PsiElement element) {
diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkAdditionalData.java b/python/src/com/jetbrains/python/sdk/PythonSdkAdditionalData.java
index c2680224e28a..c0a4226710ed 100644
--- a/python/src/com/jetbrains/python/sdk/PythonSdkAdditionalData.java
+++ b/python/src/com/jetbrains/python/sdk/PythonSdkAdditionalData.java
@@ -35,6 +35,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Set;
+import static com.intellij.openapi.util.JDOMExternalizer.loadStringsList;
+
/**
* @author traff
*/
@@ -58,16 +60,11 @@ public class PythonSdkAdditionalData implements SdkAdditionalData {
}
public Object clone() throws CloneNotSupportedException {
- try {
- final PythonSdkAdditionalData copy = (PythonSdkAdditionalData)super.clone();
- copy.setAddedPaths(getAddedPaths());
- copy.setExcludedPaths(getExcludedPaths());
- copy.setAssociatedProjectPath(getAssociatedProjectPath());
- return copy;
- }
- catch (CloneNotSupportedException e) {
- return null;
- }
+ final PythonSdkAdditionalData copy = new PythonSdkAdditionalData(myFlavor);
+ copy.setAddedPaths(getAddedPaths());
+ copy.setExcludedPaths(getExcludedPaths());
+ copy.setAssociatedProjectPath(getAssociatedProjectPath());
+ return copy;
}
public Set<SimpleProjectRoot> getAddedPaths() {
@@ -181,16 +178,6 @@ public class PythonSdkAdditionalData implements SdkAdditionalData {
return files;
}
- protected static List<String> loadStringsList(Element element, String rootName, String attrName) {
- final List<String> paths = new LinkedList<String>();
- if (element != null) {
- @NotNull final List list = element.getChildren(rootName);
- for (Object o : list) {
- paths.add(((Element)o).getAttribute(attrName).getValue());
- }
- }
- return paths;
- }
public Set<VirtualFile> getAddedPathFiles() {
return getPathsAsVirtualFiles(myAddedPaths);
diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java b/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java
index df04801e130c..3e0d4ff7e3bf 100644
--- a/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java
+++ b/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java
@@ -40,7 +40,7 @@ import java.util.Collection;
import java.util.List;
public class PythonSdkDetailsStep extends BaseListPopupStep<String> {
- private static DialogWrapper myMore;
+ private DialogWrapper myMore;
private final Project myProject;
private final Component myOwnerComponent;
private final Sdk[] myExistingSdks;
@@ -55,21 +55,20 @@ public class PythonSdkDetailsStep extends BaseListPopupStep<String> {
final Sdk[] existingSdks,
DialogWrapper moreDialog,
JComponent ownerComponent, final Point popupPoint,
- final boolean showMore,
final NullableConsumer<Sdk> callback) {
- myMore = moreDialog;
- final ListPopupStep sdkHomesStep = new PythonSdkDetailsStep(project, ownerComponent, existingSdks, showMore, callback);
+
+ final ListPopupStep sdkHomesStep = new PythonSdkDetailsStep(project, moreDialog, ownerComponent, existingSdks, callback);
final ListPopup popup = JBPopupFactory.getInstance().createListPopup(sdkHomesStep);
popup.showInScreenCoordinates(ownerComponent, popupPoint);
}
public PythonSdkDetailsStep(Project project,
- Component ownerComponent,
+ DialogWrapper moreDialog, Component ownerComponent,
Sdk[] existingSdks,
- boolean showMore,
NullableConsumer<Sdk> callback) {
- super(null, getAvailableOptions(showMore));
+ super(null, getAvailableOptions(moreDialog != null));
myProject = project;
+ myMore = moreDialog;
myOwnerComponent = ownerComponent;
myExistingSdks = existingSdks;
myCallback = callback;
@@ -154,7 +153,7 @@ public class PythonSdkDetailsStep extends BaseListPopupStep<String> {
final List<PythonSdkFlavor> flavors = PythonSdkFlavor.getApplicableFlavors(false);
for (PythonSdkFlavor flavor : flavors) {
final Collection<String> strings = flavor.suggestHomePaths();
- for (String string : strings) {
+ for (String string : SdkConfigurationUtil.filterExistingPaths(PythonSdkType.getInstance(), strings, myExistingSdks)) {
allSdks.add(new PyDetectedSdk(string));
}
}
diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java
index 6aa0c6d85df1..b13cb762cae4 100644
--- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java
+++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java
@@ -51,8 +51,8 @@ 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.remotesdk.RemoteSdkCredentials;
-import com.intellij.remotesdk.RemoteSdkCredentialsHolder;
+import com.intellij.remote.RemoteSdkCredentials;
+import com.intellij.remote.RemoteSdkCredentialsHolder;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.NullableConsumer;
@@ -282,7 +282,7 @@ public class PythonSdkType extends SdkType {
final Point point = parentComponent.getMousePosition();
SwingUtilities.convertPointToScreen(point, parentComponent);
PythonSdkDetailsStep
- .show(project, sdkModel.getSdks(), null, parentComponent, point, false, new NullableConsumer<Sdk>() {
+ .show(project, sdkModel.getSdks(), null, parentComponent, point, new NullableConsumer<Sdk>() {
@Override
public void consume(@Nullable Sdk sdk) {
if (sdk != null) {
@@ -407,18 +407,19 @@ public class PythonSdkType extends SdkType {
}
public static String suggestSdkNameFromVersion(String sdkHome, String version) {
- final String short_home_name = FileUtil.getLocationRelativeToUserHome(sdkHome);
+ sdkHome = FileUtil.toSystemDependentName(sdkHome);
+ final String shortHomeName = FileUtil.getLocationRelativeToUserHome(sdkHome);
if (version != null) {
- File virtualenv_root = getVirtualEnvRoot(sdkHome);
- if (virtualenv_root != null) {
- version += " virtualenv at " + FileUtil.getLocationRelativeToUserHome(virtualenv_root.getAbsolutePath());
+ File virtualEnvRoot = getVirtualEnvRoot(sdkHome);
+ if (virtualEnvRoot != null) {
+ version += " virtualenv at " + FileUtil.getLocationRelativeToUserHome(virtualEnvRoot.getAbsolutePath());
}
else {
- version += " (" + short_home_name + ")";
+ version += " (" + shortHomeName + ")";
}
}
else {
- version = "Unknown at " + short_home_name;
+ version = "Unknown at " + shortHomeName;
} // last resort
return version;
}
@@ -480,10 +481,10 @@ public class PythonSdkType extends SdkType {
if (flavor != null) {
VirtualFile sdkPath = flavor.getSdkPath(homePath);
if (sdkPath != null) {
- return sdkPath.getPath();
+ return FileUtil.toSystemDependentName(sdkPath.getPath());
}
}
- return path;
+ return FileUtil.toSystemDependentName(path);
}
public void setupSdkPaths(@NotNull final Sdk sdk) {
@@ -658,9 +659,9 @@ public class PythonSdkType extends SdkType {
}
public static void addSdkRoot(SdkModificator sdkModificator, String path) {
- VirtualFile child = LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
- if (child != null) {
- addSdkRoot(sdkModificator, child);
+ final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
+ if (file != null) {
+ addSdkRoot(sdkModificator, file);
}
else {
LOG.info("Bogus sys.path entry " + path);
@@ -668,19 +669,26 @@ public class PythonSdkType extends SdkType {
}
private static void addSdkRoot(@NotNull SdkModificator sdkModificator, @NotNull VirtualFile child) {
- @NonNls String suffix = child.getExtension();
- if (suffix != null) suffix = suffix.toLowerCase(); // Why on earth empty suffix is null and not ""?
- VirtualFile toAdd = child;
- if ((!child.isDirectory()) && ("zip".equals(suffix) || "egg".equals(suffix))) {
- // a .zip / .egg file must have its root extracted first
- toAdd = JarFileSystem.getInstance().getJarRootForLocalFile(child);
+ // NOTE: Files marked as library sources are not considered part of project source. Since the directory of the project the
+ // user is working on is included in PYTHONPATH with many configurations (e.g. virtualenv), we must not mark SDK paths as
+ // library sources, only as classes.
+ sdkModificator.addRoot(getSdkRootVirtualFile(child), OrderRootType.CLASSES);
+ }
+
+ @NotNull
+ public static VirtualFile getSdkRootVirtualFile(@NotNull VirtualFile path) {
+ String suffix = path.getExtension();
+ if (suffix != null) {
+ suffix = suffix.toLowerCase(); // Why on earth empty suffix is null and not ""?
}
- if (toAdd != null) {
- // NOTE: Files marked as library sources are not considered part of project source. Since the directory of the project the
- // user is working on is included in PYTHONPATH with many configurations (e.g. virtualenv), we must not mark SDK paths as
- // library sources, only as classes.
- sdkModificator.addRoot(toAdd, OrderRootType.CLASSES);
+ if ((!path.isDirectory()) && ("zip".equals(suffix) || "egg".equals(suffix))) {
+ // a .zip / .egg file must have its root extracted first
+ final VirtualFile jar = JarFileSystem.getInstance().getJarRootForLocalFile(path);
+ if (jar != null) {
+ return jar;
+ }
}
+ return path;
}
public static String getSkeletonsPath(String basePath, String sdkHome) {
diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java b/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java
index 2cc749f72002..a964fa90246e 100644
--- a/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java
+++ b/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java
@@ -31,6 +31,7 @@ import com.intellij.openapi.projectRoots.SdkTypeId;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.startup.StartupActivity;
import com.intellij.openapi.util.io.FileUtilRt;
+import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsUtil;
@@ -38,7 +39,6 @@ import com.jetbrains.python.sdk.skeletons.PySkeletonRefresher;
import org.jetbrains.annotations.NotNull;
import java.io.File;
-import java.io.IOException;
import java.util.*;
/**
@@ -135,7 +135,7 @@ public class PythonSdkUpdater implements StartupActivity {
}
}
- private static void updateSysPath(final Sdk sdk) throws InvalidSdkException {
+ private static void updateSysPath(@NotNull final Sdk sdk) throws InvalidSdkException {
long start_time = System.currentTimeMillis();
final List<String> sysPath = PythonSdkType.getSysPath(sdk.getHomePath());
final VirtualFile file = PyUserSkeletonsUtil.getUserSkeletonsDirectory();
@@ -151,9 +151,29 @@ public class PythonSdkUpdater implements StartupActivity {
LOG.info("Updating sys.path took " + (System.currentTimeMillis() - start_time) + " ms");
}
- private static void updateSdkPath(Sdk sdk, List<String> sysPath) {
+ /**
+ * Updates SDK based on sys.path and cleans legacy information up.
+ */
+ private static void updateSdkPath(@NotNull Sdk sdk, @NotNull List<String> sysPath) {
+ final SdkModificator modificator = sdk.getSdkModificator();
+ boolean changed = addNewSysPathEntries(sdk, modificator, sysPath);
+ changed = removeSourceRoots(sdk, modificator) || changed;
+ changed = removeDuplicateClassRoots(sdk, modificator) || changed;
+ if (changed) {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ modificator.commitChanges();
+ }
+ });
+ }
+ }
+
+ /**
+ * Adds new CLASSES entries found in sys.path.
+ */
+ private static boolean addNewSysPathEntries(@NotNull Sdk sdk, @NotNull SdkModificator modificator, @NotNull List<String> sysPath) {
final List<VirtualFile> oldRoots = Arrays.asList(sdk.getRootProvider().getFiles(OrderRootType.CLASSES));
- final VirtualFile[] sourceRoots = sdk.getRootProvider().getFiles(OrderRootType.SOURCES);
PythonSdkAdditionalData additionalData = sdk.getSdkAdditionalData() instanceof PythonSdkAdditionalData
? (PythonSdkAdditionalData)sdk.getSdkAdditionalData()
: null;
@@ -166,37 +186,49 @@ public class PythonSdkUpdater implements StartupActivity {
newRoots.add(root);
}
}
- if (!newRoots.isEmpty() || sourceRoots.length > 0) {
- final SdkModificator modificator = sdk.getSdkModificator();
+ if (!newRoots.isEmpty()) {
for (String root : newRoots) {
PythonSdkType.addSdkRoot(modificator, root);
}
- modificator.removeRoots(OrderRootType.SOURCES);
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @Override
- public void run() {
- modificator.commitChanges();
- }
- });
+ return true;
}
+ return false;
}
- private static boolean wasOldRoot(String root, Collection<VirtualFile> virtualFiles) {
- String rootPath = canonicalize(root);
- for (VirtualFile virtualFile : virtualFiles) {
- if (canonicalize(virtualFile.getPath()).equals(rootPath)) {
- return true;
+ /**
+ * Removes duplicate roots that have been added as the result of a bug with *.egg handling.
+ */
+ private static boolean removeDuplicateClassRoots(@NotNull Sdk sdk, @NotNull SdkModificator modificator) {
+ final List<VirtualFile> sourceRoots = Arrays.asList(sdk.getRootProvider().getFiles(OrderRootType.CLASSES));
+ final LinkedHashSet<VirtualFile> uniqueRoots = new LinkedHashSet<VirtualFile>(sourceRoots);
+ if (uniqueRoots.size() != sourceRoots.size()) {
+ modificator.removeRoots(OrderRootType.CLASSES);
+ for (VirtualFile root : uniqueRoots) {
+ modificator.addRoot(root, OrderRootType.CLASSES);
}
+ return true;
}
return false;
}
- private static String canonicalize(String path) {
- try {
- return new File(path).getCanonicalPath();
+ /**
+ * Removes legacy SOURCES entries in Python SDK tables (PY-2891).
+ */
+ private static boolean removeSourceRoots(@NotNull Sdk sdk, @NotNull SdkModificator modificator) {
+ final VirtualFile[] sourceRoots = sdk.getRootProvider().getFiles(OrderRootType.SOURCES);
+ if (sourceRoots.length > 0) {
+ modificator.removeRoots(OrderRootType.SOURCES);
+ return true;
}
- catch (IOException e) {
- return path;
+ return false;
+ }
+
+ private static boolean wasOldRoot(@NotNull String root, @NotNull Collection<VirtualFile> oldRoots) {
+ final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(root);
+ if (file != null) {
+ final VirtualFile rootFile = PythonSdkType.getSdkRootVirtualFile(file);
+ return oldRoots.contains(rootFile);
}
+ return false;
}
}
diff --git a/python/src/com/jetbrains/python/sdk/flavors/MacPythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/MacPythonSdkFlavor.java
index 5d241b668166..72c8f422f153 100644
--- a/python/src/com/jetbrains/python/sdk/flavors/MacPythonSdkFlavor.java
+++ b/python/src/com/jetbrains/python/sdk/flavors/MacPythonSdkFlavor.java
@@ -15,14 +15,14 @@
*/
package com.jetbrains.python.sdk.flavors;
+import com.intellij.openapi.util.io.FileSystemUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VFileProperty;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
+import com.intellij.util.containers.HashSet;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
+import java.util.Set;
/**
* @author yole
@@ -36,30 +36,35 @@ public class MacPythonSdkFlavor extends CPythonSdkFlavor {
@Override
public Collection<String> suggestHomePaths() {
- List<String> candidates = new ArrayList<String>();
+ Set<String> candidates = new HashSet<String>();
collectPythonInstallations("/Library/Frameworks/Python.framework/Versions", candidates);
collectPythonInstallations("/System/Library/Frameworks/Python.framework/Versions", candidates);
UnixPythonSdkFlavor.collectUnixPythons("/usr/local/bin", candidates);
return candidates;
}
- private static void collectPythonInstallations(String pythonPath, List<String> candidates) {
+ private static void collectPythonInstallations(String pythonPath, Set<String> candidates) {
VirtualFile rootVDir = LocalFileSystem.getInstance().findFileByPath(pythonPath);
if (rootVDir != null) {
if (rootVDir instanceof NewVirtualFile) {
((NewVirtualFile)rootVDir).markDirty();
}
- rootVDir.refresh(false, false);
+ rootVDir.refresh(true, false);
for (VirtualFile dir : rootVDir.getChildren()) {
- final String dir_name = dir.getName().toLowerCase();
+ final String dirName = dir.getName().toLowerCase();
if (dir.isDirectory()) {
- if ("Current".equals(dir_name) || dir_name.startsWith("2") || dir_name.startsWith("3")) {
+ if ("Current".equals(dirName) || dirName.startsWith("2") || dirName.startsWith("3")) {
final VirtualFile binDir = dir.findChild("bin");
if (binDir != null && binDir.isDirectory()) {
for (String name : POSSIBLE_BINARY_NAMES) {
final VirtualFile child = binDir.findChild(name);
- if (child != null && !child.is(VFileProperty.SYMLINK)) {
- candidates.add(child.getPath());
+ if (child == null) continue;
+ String path = child.getPath();
+ if (FileSystemUtil.isSymLink(path)) {
+ path = FileSystemUtil.resolveSymLink(path);
+ }
+ if (path != null && !candidates.contains(path)) {
+ candidates.add(path);
break;
}
}
diff --git a/python/src/com/jetbrains/python/sdk/flavors/PyRemoteSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/PyRemoteSdkFlavor.java
index 0ad83294398b..271afc6e8c2f 100644
--- a/python/src/com/jetbrains/python/sdk/flavors/PyRemoteSdkFlavor.java
+++ b/python/src/com/jetbrains/python/sdk/flavors/PyRemoteSdkFlavor.java
@@ -17,7 +17,7 @@ package com.jetbrains.python.sdk.flavors;
import com.google.common.collect.Lists;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.remotesdk.RemoteFile;
+import com.intellij.remote.RemoteFile;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
diff --git a/python/src/com/jetbrains/python/sdk/flavors/UnixPythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/UnixPythonSdkFlavor.java
index 2440661877ff..b01424b66c3a 100644
--- a/python/src/com/jetbrains/python/sdk/flavors/UnixPythonSdkFlavor.java
+++ b/python/src/com/jetbrains/python/sdk/flavors/UnixPythonSdkFlavor.java
@@ -15,14 +15,14 @@
*/
package com.jetbrains.python.sdk.flavors;
+import com.intellij.openapi.util.io.FileSystemUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VFileProperty;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
+import com.intellij.util.containers.HashSet;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
+import java.util.Set;
/**
* @author yole
@@ -37,12 +37,12 @@ public class UnixPythonSdkFlavor extends CPythonSdkFlavor {
@Override
public Collection<String> suggestHomePaths() {
- List<String> candidates = new ArrayList<String>();
+ Set<String> candidates = new HashSet<String>();
collectUnixPythons("/usr/bin", candidates);
return candidates;
}
- public static void collectUnixPythons(String path, List<String> candidates) {
+ public static void collectUnixPythons(String path, Set<String> candidates) {
VirtualFile rootDir = LocalFileSystem.getInstance().findFileByPath(path);
if (rootDir != null) {
if (rootDir instanceof NewVirtualFile) {
@@ -55,9 +55,13 @@ public class UnixPythonSdkFlavor extends CPythonSdkFlavor {
final String childName = child.getName();
for (String name : NAMES) {
if (childName.startsWith(name)) {
- if (!childName.endsWith("-config") && !childName.startsWith("pythonw") &&
- !childName.endsWith("m") && !child.is(VFileProperty.SYMLINK)) {
- candidates.add(child.getPath());
+ String childPath = child.getPath();
+ if (FileSystemUtil.isSymLink(childPath)) {
+ childPath = FileSystemUtil.resolveSymLink(childPath);
+ }
+ if (childPath != null && !childName.endsWith("-config") && !childName.startsWith("pythonw") && !childName.endsWith("m") &&
+ !candidates.contains(childPath)) {
+ candidates.add(childPath);
}
break;
}
diff --git a/python/src/com/jetbrains/python/sdk/flavors/VirtualEnvSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/VirtualEnvSdkFlavor.java
index b9de2e2c9003..b9bdf8fc11c4 100644
--- a/python/src/com/jetbrains/python/sdk/flavors/VirtualEnvSdkFlavor.java
+++ b/python/src/com/jetbrains/python/sdk/flavors/VirtualEnvSdkFlavor.java
@@ -111,7 +111,7 @@ public class VirtualEnvSdkFlavor extends CPythonSdkFlavor {
for (String name : NAMES) {
if (SystemInfo.isWindows) {
if (childName.equals(name)) {
- return child.getPath();
+ return FileUtil.toSystemDependentName(child.getPath());
}
}
else {
diff --git a/python/src/com/jetbrains/python/sdk/flavors/WinPythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/WinPythonSdkFlavor.java
index 9de862f66fac..8e75e634755b 100644
--- a/python/src/com/jetbrains/python/sdk/flavors/WinPythonSdkFlavor.java
+++ b/python/src/com/jetbrains/python/sdk/flavors/WinPythonSdkFlavor.java
@@ -40,7 +40,7 @@ public class WinPythonSdkFlavor extends CPythonSdkFlavor {
public Collection<String> suggestHomePaths() {
Set<String> candidates = new TreeSet<String>();
findInCandidatePaths(candidates, "python.exe", "jython.bat", "pypy.exe");
- candidates.add(PythonHelpersLocator.getHelpersRoot().getParent());
+ findInstallations(candidates, "python.exe", PythonHelpersLocator.getHelpersRoot().getParent());
return candidates;
}
@@ -66,7 +66,7 @@ public class WinPythonSdkFlavor extends CPythonSdkFlavor {
}
File f = new File(pathEntry, exeName);
if (f.exists()) {
- candidates.add(FileUtil.toSystemIndependentName(f.getPath()));
+ candidates.add(FileUtil.toSystemDependentName(f.getPath()));
}
}
}
@@ -81,7 +81,7 @@ public class WinPythonSdkFlavor extends CPythonSdkFlavor {
for (VirtualFile dir : rootVDir.getChildren()) {
if (dir.isDirectory() && dir.getName().toLowerCase().startsWith(dir_prefix)) {
VirtualFile python_exe = dir.findChild(exe_name);
- if (python_exe != null) candidates.add(FileUtil.toSystemIndependentName(python_exe.getPath()));
+ if (python_exe != null) candidates.add(FileUtil.toSystemDependentName(python_exe.getPath()));
}
}
}
diff --git a/python/src/com/jetbrains/python/validation/PyAnnotatingVisitor.java b/python/src/com/jetbrains/python/validation/PyAnnotatingVisitor.java
index 39ab3639751a..8accd9854acc 100644
--- a/python/src/com/jetbrains/python/validation/PyAnnotatingVisitor.java
+++ b/python/src/com/jetbrains/python/validation/PyAnnotatingVisitor.java
@@ -31,10 +31,7 @@ import java.util.List;
*/
public class PyAnnotatingVisitor implements Annotator {
private static final Logger LOGGER = Logger.getInstance(PyAnnotatingVisitor.class.getName());
-
- private final List<PyAnnotator> myAnnotators = new ArrayList<PyAnnotator>();
-
- private final Class[] ANNOTATOR_CLASSES = new Class[] {
+ private static final Class[] ANNOTATOR_CLASSES = new Class[] {
AssignTargetAnnotator.class,
ParameterListAnnotator.class,
HighlightingAnnotator.class,
@@ -44,10 +41,13 @@ public class PyAnnotatingVisitor implements Annotator {
GlobalAnnotator.class,
ImportAnnotator.class,
PyBuiltinAnnotator.class,
- UnsupportedFeatures.class
+ UnsupportedFeatures.class
};
+ private final PyAnnotator[] myAnnotators;
+
public PyAnnotatingVisitor() {
+ final List<PyAnnotator> annotators = new ArrayList<PyAnnotator>();
for (Class cls : ANNOTATOR_CLASSES) {
PyAnnotator annotator;
try {
@@ -61,13 +61,14 @@ public class PyAnnotatingVisitor implements Annotator {
LOGGER.error(e);
continue;
}
- myAnnotators.add(annotator);
+ annotators.add(annotator);
}
+ myAnnotators = annotators.toArray(new PyAnnotator[annotators.size()]);
}
public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) {
final PsiFile file = psiElement.getContainingFile();
- for(PyAnnotator annotator: myAnnotators) {
+ for (PyAnnotator annotator : myAnnotators) {
if (file instanceof PyFileImpl && !((PyFileImpl)file).isAcceptedFor(annotator.getClass())) continue;
annotator.annotateElement(psiElement, holder);
}
diff --git a/python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java b/python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java
index 417c3621d095..102867fba9a6 100644
--- a/python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java
+++ b/python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java
@@ -18,67 +18,63 @@ package com.jetbrains.python.validation;
import com.intellij.lang.ASTNode;
import com.intellij.lang.annotation.Annotation;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.ResolveResult;
-import com.jetbrains.python.highlighting.PyHighlighter;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.PyTokenTypes;
+import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
+import com.jetbrains.python.highlighting.PyHighlighter;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
+import org.jetbrains.annotations.NotNull;
/**
* Marks built-in names.
- * User: dcheryasov
- * Date: Jan 10, 2009 12:17:15 PM
+ *
+ * @author dcheryasov
*/
public class PyBuiltinAnnotator extends PyAnnotator {
@Override
public void visitPyReferenceExpression(PyReferenceExpression node) {
final String name = node.getName();
- if (name == null) return;
- boolean highlighted_as_attribute = highlightAsAttribute(node, name);
- if (! highlighted_as_attribute && !node.isQualified()) {
- // things like len()
- ResolveResult[] resolved = node.getReference().multiResolve(false); // constructors, etc may give multiple results...
- if (resolved.length > 0) {
- if (PyBuiltinCache.getInstance(node).hasInBuiltins(resolved[0].getElement())) { // ...but we only care about the default resolution
- Annotation ann;
- PsiElement parent = node.getParent();
- if (parent instanceof PyDecorator) {
- // don't mark the entire decorator, only mark the "@", else we'll conflict with deco annotator
- ann = getHolder().createInfoAnnotation(parent.getFirstChild(), null); // first child is there, or we'd not parse as deco
- }
- else ann = getHolder().createInfoAnnotation(node, null);
- ann.setTextAttributes(PyHighlighter.PY_BUILTIN_NAME);
- }
+ if (name == null) return;
+ final boolean highlightedAsAttribute = highlightAsAttribute(node, name);
+ if (!highlightedAsAttribute && PyBuiltinCache.isInBuiltins(node)) {
+ final Annotation ann;
+ final PsiElement parent = node.getParent();
+ if (parent instanceof PyDecorator) {
+ // don't mark the entire decorator, only mark the "@", else we'll conflict with deco annotator
+ ann = getHolder().createInfoAnnotation(parent.getFirstChild(), null); // first child is there, or we'd not parse as deco
+ }
+ else {
+ ann = getHolder().createInfoAnnotation(node, null);
}
+ ann.setTextAttributes(PyHighlighter.PY_BUILTIN_NAME);
}
}
@Override
public void visitPyTargetExpression(PyTargetExpression node) {
final String name = node.getName();
- if (name == null) return;
- highlightAsAttribute(node, name);
+ if (name != null) {
+ highlightAsAttribute(node, name);
+ }
}
/**
* Try to highlight a node as a class attribute.
+ *
* @param node what to work with
- * @return true iff the node was highlighted.
+ * @return true iff the node was highlighted.
*/
- private boolean highlightAsAttribute(PyQualifiedExpression node, String name) {
- LanguageLevel languageLevel = LanguageLevel.forElement(node);
+ private boolean highlightAsAttribute(@NotNull PyQualifiedExpression node, @NotNull String name) {
+ final LanguageLevel languageLevel = LanguageLevel.forElement(node);
if (PyNames.UnderscoredAttributes.contains(name) || PyNames.getBuiltinMethods(languageLevel).containsKey(name)) {
- // things like __len__
- if (
- node.isQualified() // foo.__len__
- || (PyUtil.getConcealingParent(node) instanceof PyClass) // class Foo: ... __len__ = myLenImpl
- ) {
+ // things like __len__: foo.__len__ or class Foo: ... __len__ = my_len_impl
+ if (node.isQualified() || ScopeUtil.getScopeOwner(node) instanceof PyClass) {
final ASTNode astNode = node.getNode();
if (astNode != null) {
- ASTNode tgt = astNode.findChildByType(PyTokenTypes.IDENTIFIER); // only the id, not all qualifiers subtree
+ final ASTNode tgt = astNode.findChildByType(PyTokenTypes.IDENTIFIER); // only the id, not all qualifiers subtree
if (tgt != null) {
- Annotation ann = getHolder().createInfoAnnotation(tgt, null);
+ final Annotation ann = getHolder().createInfoAnnotation(tgt, null);
ann.setTextAttributes(PyHighlighter.PY_PREDEFINED_USAGE);
return true;
}
@@ -87,5 +83,4 @@ public class PyBuiltinAnnotator extends PyAnnotator {
}
return false;
}
-
}
diff --git a/python/src/icons/PythonIcons.java b/python/src/icons/PythonIcons.java
index 2adb29d6c544..4e91858a0969 100644
--- a/python/src/icons/PythonIcons.java
+++ b/python/src/icons/PythonIcons.java
@@ -49,7 +49,6 @@ public class PythonIcons {
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
public static final Icon PythonTests = load("/icons/com/jetbrains/python/pythonTests.png"); // 16x16
- public static final Icon Skeleton = load("/icons/com/jetbrains/python/skeleton.png"); // 16x16
public static final Icon TemplateRoot = load("/icons/com/jetbrains/python/templateRoot.png"); // 16x16
public static final Icon Virtualenv = load("/icons/com/jetbrains/python/virtualenv.png"); // 16x16
diff --git a/python/testData/refactoring/extractsuperclass/properties.after.py b/python/testData/refactoring/extractsuperclass/properties.after.py
new file mode 100644
index 000000000000..e512d94e920d
--- /dev/null
+++ b/python/testData/refactoring/extractsuperclass/properties.after.py
@@ -0,0 +1,27 @@
+class ToClass(object):
+ C = 12
+
+ def __init__(self):
+ self.a = 1
+
+ def _get(self):
+ return 1
+
+ def _set(self, value):
+ pass
+
+ def _delete(self):
+ pass
+
+ old_property = property(_get, _set, _delete)
+
+ def foo(self):
+ pass
+
+
+class FromClass(ToClass):
+ def __init__(self): pass
+
+
+ def lala(self):
+ pass \ No newline at end of file
diff --git a/python/testData/refactoring/extractsuperclass/properties.before.py b/python/testData/refactoring/extractsuperclass/properties.before.py
new file mode 100644
index 000000000000..3df31fe9c31f
--- /dev/null
+++ b/python/testData/refactoring/extractsuperclass/properties.before.py
@@ -0,0 +1,22 @@
+class FromClass(object):
+ C = 12
+
+ def __init__(self):
+ self.a = 1
+
+ def _get(self):
+ return 1
+
+ def _set(self, value):
+ pass
+
+ def _delete(self):
+ pass
+
+ old_property = property(_get, _set, _delete)
+
+ def foo(self):
+ pass
+
+ def lala(self):
+ pass \ No newline at end of file
diff --git a/python/testData/refactoring/pullup/presenter/file.py b/python/testData/refactoring/pullup/presenter/file.py
index cb6ca9511209..f70f47e5875c 100644
--- a/python/testData/refactoring/pullup/presenter/file.py
+++ b/python/testData/refactoring/pullup/presenter/file.py
@@ -30,14 +30,38 @@ class BadMro(MainParent, object, SubParent1, SubParent2):
pass
class HugeChild(SubParent1, date): #SubParent1 is disabled
+ __metaclass__ = None # Anyway, this field should be ignored and processed separately as "metaclass", not "class field"
+
def __init__(self):
self.instance_field_1 = 42
self.instance_field_2 = 100500
CLASS_FIELD = 42
(CLASS_FIELD_A,CLASS_FIELD_B) = (42,100500) #We do not support tuples in class assignments for now (see ClassFieldsManager)
- def foo(self): #should be disabled
+
+ def _set(self, val): # Should not be treated as method (part of property)
pass
+
+ def _get(self): # Should not be treated as method (part of property)
+ return None
+
+ name = property(fget=_get, fset=_set)
+
+
+ @property
+ def some_property(self): # Should not be treated as method (part of property)
+ return None
+
+ @some_property.setter
+ def some_property(self, val): # Should not be treated as method (part of property)
+ pass
+
+
+
+
+
+ def foo(self): #should be disabled
+ self.some_property = 12
def bar(self):
pass
diff --git a/python/testData/refactoring/pullup/properties/Class.after.py b/python/testData/refactoring/pullup/properties/Class.after.py
new file mode 100644
index 000000000000..1291238ed082
--- /dev/null
+++ b/python/testData/refactoring/pullup/properties/Class.after.py
@@ -0,0 +1,19 @@
+from SuperClass import SuperClass
+
+
+class AnyClass(SuperClass):
+ C = 1
+
+ def __init__(self):
+ super(AnyClass, self).__init__()
+
+
+
+
+
+
+
+
+ def foo(self):
+ pass
+
diff --git a/python/testData/refactoring/pullup/properties/Class.py b/python/testData/refactoring/pullup/properties/Class.py
new file mode 100644
index 000000000000..5a091a9bd934
--- /dev/null
+++ b/python/testData/refactoring/pullup/properties/Class.py
@@ -0,0 +1,25 @@
+from SuperClass import SuperClass
+
+
+class AnyClass(SuperClass):
+ C = 1
+
+ def __init__(self):
+ super(AnyClass, self).__init__()
+
+
+ @property
+ def new_property(self):
+ return 1
+
+ @new_property.setter
+ def new_property(self, value):
+ pass
+
+ @new_property.deleter
+ def new_property(self):
+ pass
+
+ def foo(self):
+ pass
+
diff --git a/python/testData/refactoring/pullup/properties/SuperClass.after.py b/python/testData/refactoring/pullup/properties/SuperClass.after.py
new file mode 100644
index 000000000000..1b2be8de00a9
--- /dev/null
+++ b/python/testData/refactoring/pullup/properties/SuperClass.after.py
@@ -0,0 +1,15 @@
+class SuperClass(object):
+ def __init__(self):
+ pass
+
+ @property
+ def new_property(self):
+ return 1
+
+ @new_property.setter
+ def new_property(self, value):
+ pass
+
+ @new_property.deleter
+ def new_property(self):
+ pass
diff --git a/python/testData/refactoring/pullup/properties/SuperClass.py b/python/testData/refactoring/pullup/properties/SuperClass.py
new file mode 100644
index 000000000000..a41b8fdc7db1
--- /dev/null
+++ b/python/testData/refactoring/pullup/properties/SuperClass.py
@@ -0,0 +1,3 @@
+class SuperClass(object):
+ def __init__(self):
+ pass
diff --git a/python/testData/refactoring/pullup/pyPullUpInfoModel.py b/python/testData/refactoring/pullup/pyPullUpInfoModel.py
index 04f6430f2518..2f891339720c 100644
--- a/python/testData/refactoring/pullup/pyPullUpInfoModel.py
+++ b/python/testData/refactoring/pullup/pyPullUpInfoModel.py
@@ -15,12 +15,45 @@ class ChildWithDependencies(SomeParent, EmptyParent):
CLASS_FIELD_DEPENDS_ON_CLASS_FIELD_FOO = CLASS_FIELD_FOO
CLASS_FIELD_DEPENDS_ON_PARENT_FIELD = SomeParent.PARENT_CLASS_FIELD
+
def __init__(self):
SomeParent.__init__(self)
self.instance_field_bar = 42
self.depends_on_instance_field_bar = self.instance_field_bar
self.depends_on_class_field_foo = ChildWithDependencies.CLASS_FIELD_FOO
+
+ @property
+ def new_property(self):
+ return 1
+
+ def _set_prop(self, val):
+ pass
+
+ def _get_prop(self):
+ return 1
+
+ def _del_prop(self):
+ pass
+
+ old_property = property(fset=_set_prop)
+ old_property_2 = property(fget=_get_prop)
+ old_property_3 = property(fdel=_del_prop)
+
+
+ @property
+ def new_property(self):
+ return 1
+
+ @new_property.setter
+ def new_property(self, val):
+ pass
+
+ @property
+ def new_property_2(self):
+ return 1
+
+
def normal_method(self):
pass
@@ -36,4 +69,14 @@ class ChildWithDependencies(SomeParent, EmptyParent):
self.normal_method()
def method_depends_on_instance_field_bar(self):
- eggs = self.instance_field_bar \ No newline at end of file
+ eggs = self.instance_field_bar
+
+ def method_depends_on_old_property(self):
+ i = 12
+ self.old_property = i
+ q = self.old_property_2
+ del self.old_property_3
+
+ def method_depends_on_new_property(self):
+ self.new_property = 12
+ print(self.new_property_2)
diff --git a/python/testSrc/com/jetbrains/python/PyEncodingTest.java b/python/testSrc/com/jetbrains/python/PyEncodingTest.java
index cccd6d45cfde..608b8396c04a 100644
--- a/python/testSrc/com/jetbrains/python/PyEncodingTest.java
+++ b/python/testSrc/com/jetbrains/python/PyEncodingTest.java
@@ -15,12 +15,12 @@
*/
package com.jetbrains.python;
-import junit.framework.TestCase;
+import com.jetbrains.python.fixtures.PyTestCase;
/**
* @author yole
*/
-public class PyEncodingTest extends TestCase {
+public class PyEncodingTest extends PyTestCase {
public void testEncodingEmacs() {
doTest("#!/usr/bin/python\n# -*- coding: iso-8859-15 -*-\nimport os, sys", "iso-8859-15");
}
@@ -33,7 +33,8 @@ public class PyEncodingTest extends TestCase {
doTest("#!/usr/local/bin/python\n# coding: latin-1\nimport os, sys", "iso-8859-1");
}
- private static void doTest(final String text, final String expected) {
- assertEquals(expected, PythonFileType.getCharsetFromEncodingDeclaration(text));
+ private void doTest(final String text, final String expected) {
+ myFixture.configureByText(PythonFileType.INSTANCE, text);
+ assertEquals(expected, PythonFileType.getCharsetFromEncodingDeclaration(myFixture.getFile()));
}
}
diff --git a/python/testSrc/com/jetbrains/python/PyTypeParserTest.java b/python/testSrc/com/jetbrains/python/PyTypeParserTest.java
index 30dc43404a3c..7db230a1d7c1 100644
--- a/python/testSrc/com/jetbrains/python/PyTypeParserTest.java
+++ b/python/testSrc/com/jetbrains/python/PyTypeParserTest.java
@@ -252,7 +252,7 @@ public class PyTypeParserTest extends PyTestCase {
final PyCallableType callableType = (PyCallableType)type;
assertNotNull(callableType);
final TypeEvalContext context = getTypeEvalContext();
- final PyType returnType = callableType.getCallType(context, null);
+ final PyType returnType = callableType.getReturnType(context);
assertInstanceOf(returnType, PyGenericType.class);
final List<PyCallableParameter> parameterTypes = callableType.getParameters(context);
assertNotNull(parameterTypes);
@@ -271,7 +271,7 @@ public class PyTypeParserTest extends PyTestCase {
assertInstanceOf(type, PyCallableType.class);
final PyCallableType callableType = (PyCallableType)type;
assertNotNull(callableType);
- final PyType returnType = callableType.getCallType(getTypeEvalContext(), null);
+ final PyType returnType = callableType.getReturnType(getTypeEvalContext());
assertNotNull(returnType);
assertEquals("int", returnType.getName());
final List<PyCallableParameter> parameterTypes = callableType.getParameters(getTypeEvalContext());
diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java
index 13d5b4d4f253..c96bdc2397e1 100644
--- a/python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java
+++ b/python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java
@@ -125,6 +125,11 @@ public class PyExtractSuperclassTest extends PyClassRefactoringTest {
doSimpleTest("FromClass", "ToClass", null, true, "#instance_field", "#CLASS_FIELD");
}
+
+ public void testProperties() throws Exception {
+ doSimpleTest("FromClass", "ToClass", null, true, "#C", "#a", "._get", ".foo");
+ }
+
private void doSimpleTest(final String className,
final String superclassName,
final String expectedError,
diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpInfoModelTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpInfoModelTest.java
index 9fe02c302c9a..3e5e508901d7 100644
--- a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpInfoModelTest.java
+++ b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpInfoModelTest.java
@@ -69,6 +69,27 @@ public class PyPullUpInfoModelTest extends PyTestCase {
Assert.assertThat("Instance on member dependencies failed", getErrorMemberNames(), Matchers.containsInAnyOrder("self.instance_field_bar"));
}
+ /**
+ * Check dependnecies for properties, declared in old-style
+ *
+ */
+ public void testOldProperty() throws Exception {
+ checkMembers("method_depends_on_old_property(self)");
+ Assert.assertThat("Method on old property dependency failed", getErrorMemberNames(), Matchers.containsInAnyOrder(
+ "old_property",
+ "old_property_2",
+ "old_property_3"));
+ }
+
+ /**
+ *
+ * Check dependnecies for properties, declared in new-style
+ */
+ public void testNewProperty() throws Exception {
+ checkMembers("method_depends_on_new_property(self)");
+ Assert.assertThat("Method on new property dependency failed", getErrorMemberNames(), Matchers.containsInAnyOrder("new_property", "new_property_2"));
+ }
+
/**
* All dependencies are met: new (destination) class has all of them
diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java
index ee5371cf24b4..1ee20d27f62a 100644
--- a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java
+++ b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java
@@ -144,7 +144,9 @@ public class PyPullUpPresenterTest extends PyRefactoringPresenterTestCase<PyPull
new PyPresenterTestMemberEntry("static_2()", true, true, py3K),
new PyPresenterTestMemberEntry("self.instance_field_1", true, false, false),
new PyPresenterTestMemberEntry("self.instance_field_2", true, false, false),
- new PyPresenterTestMemberEntry("bad_method()", true, false, true));
+ new PyPresenterTestMemberEntry("bad_method()", true, false, true),
+ new PyPresenterTestMemberEntry("name", true, false, false),
+ new PyPresenterTestMemberEntry("some_property", true, false, false));
compareMembers(memberNamesAndStatus, matcher);
}
diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpTest.java
index d725c1736083..fbf568807e40 100644
--- a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpTest.java
+++ b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpTest.java
@@ -97,6 +97,13 @@ public class PyPullUpTest extends PyClassRefactoringTest {
doMultiFileTest();
}
+ public void testProperties() {
+ final String[] modules = {"Class", "SuperClass"};
+ configureMultiFile(modules);
+ doPullUp("AnyClass", "SuperClass", ".new_property");
+ checkMultiFile(modules);
+ }
+
public void testFieldMove() {
final String[] modules = {"Class", "SuperClass"};
configureMultiFile(modules);
diff --git a/resources-en/src/messages/DebuggerBundle.properties b/resources-en/src/messages/DebuggerBundle.properties
index 57e0ec144aec..1a08b7c57386 100644
--- a/resources-en/src/messages/DebuggerBundle.properties
+++ b/resources-en/src/messages/DebuggerBundle.properties
@@ -320,10 +320,10 @@ class.filters.dialog.exclusion.filters.group=Class Exclusion Filters
instance.filters.dialog.title=Instance Filters
instance.filters.dialog.instance.filters.group=Instance Filters
breakpoint.exception.breakpoint.display.name=''{0}''
-exception.breakpoints.tab.title=Exception Breakpoints
-field.watchpoints.tab.title=Field Watchpoints
-line.breakpoints.tab.title=Line Breakpoints
-method.breakpoints.tab.title=Method Breakpoints
+exception.breakpoints.tab.title=Java Exception Breakpoints
+field.watchpoints.tab.title=Java Field Watchpoints
+line.breakpoints.tab.title=Java Line Breakpoints
+method.breakpoints.tab.title=Java Method Breakpoints
title.error.evaluating.breakpoint.condition=Breakpoint Condition Error
title.error.evaluating.breakpoint.action=Breakpoint Action Error
error.evaluating.breakpoint.condition.or.action=Problem processing VM event:\nBreakpoint: ''{0}''\nError: {1}\nWould you like to stop at the breakpoint?
@@ -446,5 +446,3 @@ error.corrupt.debug.info=Debug info might be corrupt: {0}
action.kill.process.text=Kill Process
action.kill.process.description=Forcibly terminate debugged application
evaluation.error.unknown.method.return.type=Cannot resolve method return type: {0}
-
-java.breakpoint.title=Java Line Breakpoints
diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml
index d04e05907fa8..ff39c265a942 100644
--- a/resources/src/META-INF/IdeaPlugin.xml
+++ b/resources/src/META-INF/IdeaPlugin.xml
@@ -86,9 +86,6 @@
<extensionPoint name="debugger.nodeRenderer"
interface="com.intellij.debugger.ui.tree.render.NodeRenderer"/>
- <extensionPoint name="debugger.breakpointFactory"
- interface="com.intellij.debugger.ui.breakpoints.BreakpointFactory"/>
-
<extensionPoint name="debugger.jvmDebugProvider"
interface="com.intellij.debugger.engine.JVMDebugProvider"/>
@@ -627,7 +624,7 @@
groupName="Java language level migration aids" enabledByDefault="true" level="WARNING"
implementationClass="com.intellij.codeInspection.AnonymousCanBeLambdaInspection" />
<localInspection language="JAVA" shortName="Convert2streamapi" displayName="foreach loop can be collapsed with stream api"
- groupName="Java language level migration aids" enabledByDefault="true" level="WARNING" implementationClass="com.intellij.codeInspection.StreamApiMigrationInspection"/>
+ groupName="Java language level migration aids" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.intellij.codeInspection.StreamApiMigrationInspection"/>
<localInspection language="JAVA" shortName="Anonymous2MethodRef" displayName="Anonymous type can be replaced with method reference"
groupName="Java language level migration aids" enabledByDefault="true" level="WARNING"
implementationClass="com.intellij.codeInspection.AnonymousCanBeMethodReferenceInspection" />
@@ -1378,11 +1375,11 @@
<resolveScopeEnlarger implementation="com.intellij.psi.NonClasspathResolveScopeEnlarger"/>
<xdebugger.debuggerSupport implementation="com.intellij.debugger.ui.JavaDebuggerSupport"/>
- <debugger.breakpointFactory implementation="com.intellij.debugger.ui.breakpoints.LineBreakpointFactory"/>
- <debugger.breakpointFactory implementation="com.intellij.debugger.ui.breakpoints.ExceptionBreakpointFactory"/>
- <debugger.breakpointFactory implementation="com.intellij.debugger.ui.breakpoints.AnyExceptionBreakpointFactory"/>
- <debugger.breakpointFactory implementation="com.intellij.debugger.ui.breakpoints.FieldBreakpointFactory"/>
- <debugger.breakpointFactory implementation="com.intellij.debugger.ui.breakpoints.MethodBreakpointFactory"/>
+ <xdebugger.breakpointType implementation="com.intellij.debugger.ui.breakpoints.JavaMethodBreakpointType"/>
+ <xdebugger.breakpointType implementation="com.intellij.debugger.ui.breakpoints.JavaWildcardMethodBreakpointType"/>
+ <xdebugger.breakpointType implementation="com.intellij.debugger.ui.breakpoints.JavaFieldBreakpointType"/>
+ <xdebugger.breakpointType implementation="com.intellij.debugger.ui.breakpoints.JavaExceptionBreakpointType"/>
+ <xdebugger.breakpointType implementation="com.intellij.debugger.ui.breakpoints.JavaLineBreakpointType"/>
<debugger.jvmSmartStepIntoHandler implementation="com.intellij.debugger.actions.JavaSmartStepIntoHandler"/>
<applicationService serviceInterface="com.intellij.remoteServer.runtime.deployment.debug.JavaDebuggerLauncher"
@@ -1461,8 +1458,6 @@
<codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.jarFinder.FindJarQuickFixProvider"/>
- <xdebugger.breakpointType implementation="org.jetbrains.java.debugger.breakpoints.JavaBreakpointType"/>
-
<refactoring.pullUpHelperFactory language="JAVA" implementationClass="com.intellij.refactoring.memberPullUp.JavaPullUpHelperFactory"/>
<hierarchy.referenceProcessor implementation="com.intellij.ide.hierarchy.call.JavaCallReferenceProcessor"/>
<projectTemplate projectType="JAVA_MODULE" templatePath="resources/projectTemplates/Java/Command_Line_App.zip"/>
diff --git a/spellchecker/src/com/intellij/spellchecker/english.dic b/spellchecker/src/com/intellij/spellchecker/english.dic
index 169e4c20e7ab..0047044678a5 100644
--- a/spellchecker/src/com/intellij/spellchecker/english.dic
+++ b/spellchecker/src/com/intellij/spellchecker/english.dic
@@ -68545,6 +68545,7 @@ funding
fundraiser
fundraisers
funds
+fundraising
funeral
funeral's
funerals
diff --git a/updater/src/com/intellij/updater/Runner.java b/updater/src/com/intellij/updater/Runner.java
index 9a88ea491eeb..d0143a946b0c 100755
--- a/updater/src/com/intellij/updater/Runner.java
+++ b/updater/src/com/intellij/updater/Runner.java
@@ -24,15 +24,13 @@ public class Runner {
private static final String NEW_BUILD_DESCRIPTION = "new.build.description";
public static void main(String[] args) throws Exception {
- if (args.length >= 7 && "create".equals(args[0])) {
+ if (args.length >= 6 && "create".equals(args[0])) {
String oldVersionDesc = args[1];
String newVersionDesc = args[2];
String oldFolder = args[3];
String newFolder = args[4];
String patchFile = args[5];
-
- String logFolder = args[6];
- initLogger(logFolder);
+ initLogger();
List<String> ignoredFiles = extractFiles(args, "ignored");
List<String> criticalFiles = extractFiles(args, "critical");
@@ -40,8 +38,7 @@ public class Runner {
create(oldVersionDesc, newVersionDesc, oldFolder, newFolder, patchFile, ignoredFiles, criticalFiles, optionalFiles);
}
else if (args.length >= 2 && "install".equals(args[0])) {
- // install [--exit0] <destination_folder> [log_directory]
- int max = 3;
+ // install [--exit0] <destination_folder>
int nextArg = 1;
// Default install exit code is SwingUpdaterUI.RESULT_REQUIRES_RESTART (42) unless overridden to be 0.
@@ -50,13 +47,10 @@ public class Runner {
if (args[nextArg].equals("--exit0")) {
useExitCode0 = true;
nextArg++;
- max++;
}
String destFolder = args[nextArg++];
-
- String logFolder = args.length >= max ? args[nextArg] : null;
- initLogger(logFolder);
+ initLogger();
logger.info("destFolder: " + destFolder);
install(useExitCode0, destFolder);
@@ -72,7 +66,8 @@ public class Runner {
return fileLogDir.isDirectory() && fileLogDir.canWrite() && fileLogDir.getUsableSpace() >= 1000000;
}
- private static String getLogDir(String logFolder) {
+ private static String getLogDir() {
+ String logFolder = System.getProperty("idea.updater.log");
if (logFolder == null || !isValidLogDir(logFolder)) {
logFolder = System.getProperty("java.io.tmpdir");
if (!isValidLogDir(logFolder)) {
@@ -82,9 +77,9 @@ public class Runner {
return logFolder;
}
- public static void initLogger(String logFolder) {
+ public static void initLogger() {
if (logger == null) {
- logFolder = getLogDir(logFolder);
+ String logFolder = getLogDir();
FileAppender update = new FileAppender();
update.setFile(new File(logFolder, "idea_updater.log").getAbsolutePath());
@@ -97,7 +92,6 @@ public class Runner {
updateError.setFile(new File(logFolder, "idea_updater_error.log").getAbsolutePath());
updateError.setLayout(new PatternLayout("%d{dd MMM yyyy HH:mm:ss} %-5p %C{1}.%M - %m%n"));
updateError.setThreshold(Level.ERROR);
- // The error(s) from an old run of the updater (if there were) could be found in idea_updater.log file
updateError.setAppend(false);
updateError.activateOptions();
@@ -239,17 +233,20 @@ public class Runner {
in.close();
}
- SwingUtilities.invokeAndWait(new Runnable() {
- @Override
- public void run() {
- try {
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- }
- catch (Exception ignore) {
- printStackTrace(ignore);
+ // todo[r.sh] to delete in IDEA 14 (after a full circle of platform updates)
+ if (System.getProperty("swing.defaultlaf") == null) {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ }
+ catch (Exception ignore) {
+ printStackTrace(ignore);
+ }
}
- }
- });
+ });
+ }
new SwingUpdaterUI(props.getProperty(OLD_BUILD_DESCRIPTION),
props.getProperty(NEW_BUILD_DESCRIPTION),
diff --git a/updater/testSrc/com/intellij/updater/DigesterTest.java b/updater/testSrc/com/intellij/updater/DigesterTest.java
index a7ec965359ee..3b524f8288e9 100644
--- a/updater/testSrc/com/intellij/updater/DigesterTest.java
+++ b/updater/testSrc/com/intellij/updater/DigesterTest.java
@@ -10,12 +10,12 @@ import static org.junit.Assert.assertEquals;
public class DigesterTest extends UpdaterTestCase {
@Test
public void testBasics() throws Exception {
+ Runner.initLogger();
Map<String, Long> checkSums = Digester.digestFiles(getDataDir(), Collections.<String>emptyList(), TEST_UI);
assertEquals(12, checkSums.size());
assertEquals(CHECKSUMS.README_TXT, (long)checkSums.get("Readme.txt"));
assertEquals(CHECKSUMS.FOCUSKILLER_DLL, (long)checkSums.get("bin/focuskiller.dll"));
assertEquals(CHECKSUMS.BOOTSTRAP_JAR, (long)checkSums.get("lib/bootstrap.jar"));
- Runner.initLogger(System.getProperty("java.io.tmpdir"));
}
} \ No newline at end of file
diff --git a/updater/testSrc/com/intellij/updater/RunnerTest.java b/updater/testSrc/com/intellij/updater/RunnerTest.java
index 4813db1711b3..22464a0fa053 100644
--- a/updater/testSrc/com/intellij/updater/RunnerTest.java
+++ b/updater/testSrc/com/intellij/updater/RunnerTest.java
@@ -11,7 +11,7 @@ public class RunnerTest extends UpdaterTestCase {
@Test
public void testExtractingFiles() throws Exception {
String[] args = {"bar", "ignored=xxx;yyy;zzz/zzz", "critical=", "ignored=aaa", "baz", "critical=ccc"};
- Runner.initLogger(System.getProperty("java.io.tmpdir"));
+ Runner.initLogger();
assertEquals(Arrays.asList("xxx", "yyy", "zzz/zzz", "aaa"),
Runner.extractFiles(args, "ignored"));
diff --git a/updater/testSrc/com/intellij/updater/UpdaterTestCase.java b/updater/testSrc/com/intellij/updater/UpdaterTestCase.java
index 82d7bbe860c7..dea5fbdd7c6d 100644
--- a/updater/testSrc/com/intellij/updater/UpdaterTestCase.java
+++ b/updater/testSrc/com/intellij/updater/UpdaterTestCase.java
@@ -25,7 +25,7 @@ public abstract class UpdaterTestCase {
@Before
public void setUp() throws Exception {
- Runner.initLogger(System.getProperty("java.io.tmpdir"));
+ Runner.initLogger();
myTempDirFixture = IdeaTestFixtureFactory.getFixtureFactory().createTempDirTestFixture();
myTempDirFixture.setUp();
diff --git a/xml/dom-impl/src/com/intellij/util/xml/DomFileIndex.java b/xml/dom-impl/src/com/intellij/util/xml/DomFileIndex.java
index 493f6a50ccda..7ca36a62c2f2 100644
--- a/xml/dom-impl/src/com/intellij/util/xml/DomFileIndex.java
+++ b/xml/dom-impl/src/com/intellij/util/xml/DomFileIndex.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.
@@ -84,11 +84,13 @@ public class DomFileIndex extends ScalarIndexExtension<String>{
return myDataIndexer;
}
+ @NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return new EnumeratorStringDescriptor();
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new DefaultFileTypeSpecificInputFilter(StdFileTypes.XML);
diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomApplicationComponent.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomApplicationComponent.java
index f99567085e8e..c2687fddc860 100644
--- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomApplicationComponent.java
+++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomApplicationComponent.java
@@ -96,8 +96,10 @@ public class DomApplicationComponent {
public int getCumulativeVersion() {
int result = 0;
for (DomFileDescription description : getAllFileDescriptions()) {
- result += description.getVersion();
- result += description.getRootTagName().hashCode(); // so that a plugin enabling/disabling could trigger the reindexing
+ if (description.hasStubs()) {
+ result += description.getStubVersion();
+ result += description.getRootTagName().hashCode(); // so that a plugin enabling/disabling could trigger the reindexing
+ }
}
return result;
}
diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionData.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionData.java
index 4249986cf002..8446e8872b58 100644
--- a/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionData.java
+++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionData.java
@@ -218,8 +218,9 @@ public class XmlCompletionData extends CompletionData {
containingFile = (XmlFile)document.getContainingFile();
final FileType ft = containingFile.getFileType();
-
- if(ft != StdFileTypes.XML) {
+ if (HtmlUtil.isHtml5Document(document)) {
+ descriptorFile = XmlUtil.findXmlFile(containingFile, Html5SchemaProvider.getCharsDtdLocation());
+ } else if(ft != StdFileTypes.XML) {
final String namespace = ft == StdFileTypes.XHTML || ft == StdFileTypes.JSPX ? XmlUtil.XHTML_URI : XmlUtil.HTML_URI;
final XmlNSDescriptor nsDescriptor = document.getDefaultNSDescriptor(namespace, true);
diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/HtmlSelectioner.java b/xml/impl/src/com/intellij/codeInsight/editorActions/HtmlSelectioner.java
index e724f7b1945e..be9035661247 100644
--- a/xml/impl/src/com/intellij/codeInsight/editorActions/HtmlSelectioner.java
+++ b/xml/impl/src/com/intellij/codeInsight/editorActions/HtmlSelectioner.java
@@ -32,6 +32,7 @@ import com.intellij.lang.Language;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.UnfairTextRange;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -107,8 +108,8 @@ public class HtmlSelectioner extends AbstractWordSelectioner {
final ASTNode tagStartEnd = XmlChildRole.START_TAG_END_FINDER.findChild(tag.getNode());
final ASTNode tagEndStart = XmlChildRole.CLOSING_TAG_START_FINDER.findChild(tag.getNode());
if (tagStartEnd != null && tagEndStart != null) {
- result.add(new TextRange(tagStartEnd.getTextRange().getEndOffset(),
- tagEndStart.getTextRange().getStartOffset()));
+ result.add(new UnfairTextRange(tagStartEnd.getTextRange().getEndOffset(),
+ tagEndStart.getTextRange().getStartOffset()));
}
if (tagStartEnd != null) {
result.add(new TextRange(tag.getTextRange().getStartOffset(),
diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java
index 922d910dffc2..e483f34b61c5 100644
--- a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java
+++ b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.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,31 +18,34 @@ 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 boolean needToInsertQuotes = false;
+ private List<Caret> caretsForInsertingQuotes = ContainerUtil.newSmartList();
@Override
- public Result beforeCharTyped(char c,
- Project project,
- Editor editor,
- PsiFile file,
- FileType fileType) {
+ public Result beforeCharTyped(char c, Project project, Editor editor, PsiFile file, FileType fileType) {
if (WebEditorOptions.getInstance().isInsertQuotesForAttributeValue()) {
boolean inXml = file.getLanguage() instanceof XMLLanguage || file.getViewProvider().getBaseLanguage() instanceof XMLLanguage;
if (c == '=' && inXml) {
- int offset = editor.getCaretModel().getOffset();
- PsiElement at = file.findElementAt(offset - 1);
- PsiElement atParent = at != null ? at.getParent() : null;
- needToInsertQuotes = atParent instanceof XmlAttribute && ((XmlAttribute)atParent).getValueElement() == null;
+ 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);
+ }
+ }
}
}
@@ -51,13 +54,14 @@ public class XmlEqTypedHandler extends TypedHandlerDelegate {
@Override
public Result charTyped(char c, Project project, @NotNull Editor editor, @NotNull PsiFile file) {
- if (needToInsertQuotes) {
- int offset = editor.getCaretModel().getOffset();
- editor.getDocument().insertString(offset, "\"\"");
- editor.getCaretModel().moveToOffset(offset + 1);
+ for (Caret caret : caretsForInsertingQuotes) {
+ editor.getDocument().insertString(caret.getOffset(), "\"\"");
+ caret.moveCaretRelatively(1, 0, false, true);
+ }
+ if (editor.getCaretModel().getAllCarets().size() == caretsForInsertingQuotes.size()) {
AutoPopupController.getInstance(project).scheduleAutoPopup(editor);
}
- needToInsertQuotes = false;
+ caretsForInsertingQuotes.clear();
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 e76b5a3447e2..fcebe19a8f67 100644
--- a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlGtTypedHandler.java
+++ b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlGtTypedHandler.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,9 @@ 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;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
@@ -37,12 +39,15 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.*;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.xml.XmlElementDescriptor;
import com.intellij.xml.XmlElementDescriptorWithCDataContent;
import com.intellij.xml.util.HtmlUtil;
import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.NonNls;
+import java.util.Collection;
+
public class XmlGtTypedHandler extends TypedHandlerDelegate {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.editorActions.TypedHandler");
@@ -88,9 +93,8 @@ public class XmlGtTypedHandler extends TypedHandlerDelegate {
}
if (tokenType == XmlTokenType.XML_TAG_END ||
- tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END && element.getTextOffset() == offset - 1
- ) {
- editor.getCaretModel().moveToOffset(offset + 1);
+ tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END && element.getTextOffset() == offset - 1) {
+ EditorModificationUtil.moveAllCaretsRelatively(editor, 1);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
return Result.STOP;
}
@@ -149,10 +153,9 @@ public class XmlGtTypedHandler extends TypedHandlerDelegate {
if (!(element instanceof XmlTag)) {
if (element instanceof XmlTokenImpl &&
element.getPrevSibling() !=null &&
- element.getPrevSibling().getText().equals("<")
- ) {
+ element.getPrevSibling().getText().equals("<")) {
// tag is started and there is another text in the end
- editor.getDocument().insertString(offset, "</" + element.getText() + ">");
+ EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, "</" + element.getText() + ">", false, 0);
}
return Result.CONTINUE;
}
@@ -230,36 +233,38 @@ public class XmlGtTypedHandler extends TypedHandlerDelegate {
if (hasBalance) return Result.CONTINUE;
}
- TextRange cdataReformatRange = null;
+ Collection<TextRange> cdataReformatRanges = null;
final XmlElementDescriptor descriptor = tag.getDescriptor();
if (descriptor instanceof XmlElementDescriptorWithCDataContent) {
final XmlElementDescriptorWithCDataContent cDataContainer = (XmlElementDescriptorWithCDataContent)descriptor;
+ cdataReformatRanges = ContainerUtil.newSmartList();
if (cDataContainer.requiresCdataBracesInContext(tag)) {
- int rangeStart = offset;
@NonNls final String cDataStart = "><![CDATA[";
final String inserted = cDataStart + "\n]]>";
- editor.getDocument().insertString(offset, inserted);
- final int newoffset = offset + cDataStart.length();
- editor.getCaretModel().moveToOffset(newoffset);
- offset += inserted.length();
- cdataReformatRange = new TextRange(rangeStart, offset + 1);
+ 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()));
+ }
+ }
}
}
- editor.getDocument().insertString(offset, "</" + name + ">");
+ EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, "</" + name + ">", false, 0);
- if (cdataReformatRange != null) {
+ if (cdataReformatRanges != null && !cdataReformatRanges.isEmpty()) {
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
try {
- CodeStyleManager.getInstance(project).reformatText(file, cdataReformatRange.getStartOffset(), cdataReformatRange.getEndOffset());
+ CodeStyleManager.getInstance(project).reformatText(file, cdataReformatRanges);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
- return cdataReformatRange != null ? Result.STOP : Result.CONTINUE;
+ return cdataReformatRanges != null && !cdataReformatRanges.isEmpty() ? Result.STOP : Result.CONTINUE;
}
return Result.CONTINUE;
}
diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java
index 35e772737b81..9824d444557d 100644
--- a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java
+++ b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.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 XmlSlashTypedHandler extends TypedHandlerDelegate implements XmlTok
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
final int offset = editor.getCaretModel().getOffset();
+ if (file == null) return Result.CONTINUE;
FileViewProvider provider = file.getViewProvider();
PsiElement element = provider.findElementAt(offset, XMLLanguage.class);
@@ -71,6 +72,7 @@ public class XmlSlashTypedHandler extends TypedHandlerDelegate implements XmlTok
PsiDocumentManager.getInstance(project).commitAllDocuments();
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
+ if (file == null) return Result.CONTINUE;
FileViewProvider provider = file.getViewProvider();
final int offset = editor.getCaretModel().getOffset();
PsiElement element = provider.findElementAt(offset - 1, XMLLanguage.class);
@@ -91,7 +93,7 @@ public class XmlSlashTypedHandler extends TypedHandlerDelegate implements XmlTok
tag = tag1;
}
}
- EditorModificationUtil.insertStringAtCaret(editor, tag.getName() + ">");
+ EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, tag.getName() + ">", false);
return Result.STOP;
}
}
@@ -100,7 +102,7 @@ public class XmlSlashTypedHandler extends TypedHandlerDelegate implements XmlTok
while((prevLeaf = TreeUtil.prevLeaf(prevLeaf)) != null && prevLeaf.getElementType() == XmlTokenType.XML_WHITE_SPACE);
if(prevLeaf instanceof OuterLanguageElement) {
element = file.getViewProvider().findElementAt(offset - 1, file.getLanguage());
- prevLeaf = element.getNode();
+ prevLeaf = element != null ? element.getNode() : null;
while((prevLeaf = TreeUtil.prevLeaf(prevLeaf)) != null && prevLeaf.getElementType() == XmlTokenType.XML_WHITE_SPACE);
}
if(prevLeaf == null) return Result.CONTINUE;
@@ -118,7 +120,7 @@ public class XmlSlashTypedHandler extends TypedHandlerDelegate implements XmlTok
if (XmlUtil.getTokenOfType(tag, XmlTokenType.XML_EMPTY_ELEMENT_END) != null) return Result.CONTINUE;
if (PsiTreeUtil.getParentOfType(element, XmlAttributeValue.class) != null) return Result.CONTINUE;
- EditorModificationUtil.insertStringAtCaret(editor, ">");
+ EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, ">", false);
return Result.STOP;
}
return Result.CONTINUE;
diff --git a/xml/impl/src/com/intellij/html/index/Html5CustomAttributesIndex.java b/xml/impl/src/com/intellij/html/index/Html5CustomAttributesIndex.java
index ed0538bf6820..984bd4997ba0 100644
--- a/xml/impl/src/com/intellij/html/index/Html5CustomAttributesIndex.java
+++ b/xml/impl/src/com/intellij/html/index/Html5CustomAttributesIndex.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,16 +86,18 @@ public class Html5CustomAttributesIndex extends ScalarIndexExtension<String> {
return myIndexer;
}
+ @NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return new EnumeratorStringDescriptor();
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new DefaultFileTypeSpecificInputFilter(StdFileTypes.HTML, StdFileTypes.XHTML) {
@Override
- public boolean acceptInput(final VirtualFile file) {
+ public boolean acceptInput(@NotNull final VirtualFile file) {
return file.isInLocalFileSystem();
}
};
diff --git a/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java b/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java
index cd62adf16f1d..1b2fabde81b3 100644
--- a/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java
+++ b/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.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.
@@ -26,6 +26,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.colors.EditorFontType;
+import com.intellij.openapi.editor.event.CaretAdapter;
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.extensions.Extensions;
@@ -103,7 +104,7 @@ public class BreadcrumbsXmlWrapper implements BreadcrumbsItemListener<Breadcrumb
myInfoProvider = findInfoProvider(findViewProvider(myFile, myProject));
- final CaretListener caretListener = new CaretListener() {
+ final CaretListener caretListener = new CaretAdapter() {
public void caretPositionChanged(final CaretEvent e) {
if (myUserCaretChange) {
queueUpdate(editor);
diff --git a/xml/impl/src/com/intellij/xml/index/SchemaTypeInheritanceIndex.java b/xml/impl/src/com/intellij/xml/index/SchemaTypeInheritanceIndex.java
index 515522185339..f504b66ba754 100644
--- a/xml/impl/src/com/intellij/xml/index/SchemaTypeInheritanceIndex.java
+++ b/xml/impl/src/com/intellij/xml/index/SchemaTypeInheritanceIndex.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.
@@ -133,11 +133,12 @@ public class SchemaTypeInheritanceIndex extends XmlIndex<Set<SchemaTypeInfo>> {
};
}
+ @NotNull
@Override
public DataExternalizer<Set<SchemaTypeInfo>> getValueExternalizer() {
return new DataExternalizer<Set<SchemaTypeInfo>>() {
@Override
- public void save(DataOutput out, Set<SchemaTypeInfo> value) throws IOException {
+ public void save(@NotNull DataOutput out, Set<SchemaTypeInfo> value) throws IOException {
out.writeInt(value.size());
for (SchemaTypeInfo key : value) {
out.writeUTF(key.getNamespaceUri());
@@ -147,7 +148,7 @@ public class SchemaTypeInheritanceIndex extends XmlIndex<Set<SchemaTypeInfo>> {
}
@Override
- public Set<SchemaTypeInfo> read(DataInput in) throws IOException {
+ public Set<SchemaTypeInfo> read(@NotNull DataInput in) throws IOException {
final Set<SchemaTypeInfo> set = new HashSet<SchemaTypeInfo>();
final int size = in.readInt();
for (int i = 0; i < size; i++) {
diff --git a/xml/impl/src/com/intellij/xml/index/XmlTagNamesIndex.java b/xml/impl/src/com/intellij/xml/index/XmlTagNamesIndex.java
index 97fb7c0d3d53..b3fc55c1a857 100644
--- a/xml/impl/src/com/intellij/xml/index/XmlTagNamesIndex.java
+++ b/xml/impl/src/com/intellij/xml/index/XmlTagNamesIndex.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,6 +70,7 @@ public class XmlTagNamesIndex extends XmlIndex<Void> {
};
}
+ @NotNull
@Override
public DataExternalizer<Void> getValueExternalizer() {
return ScalarIndexExtension.VOID_DATA_EXTERNALIZER;
diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java
index eede27a5a2b9..a00d40dd1172 100644
--- a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java
+++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.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.intellij.plugins.relaxNG.model.resolve;
import com.intellij.ide.highlighter.XmlFileType;
@@ -129,16 +144,18 @@ public class RelaxSymbolIndex extends ScalarIndexExtension<String> {
};
}
+ @NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return new EnumeratorStringDescriptor();
}
+ @NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new DefaultFileTypeSpecificInputFilter(StdFileTypes.XML, RncFileType.getInstance()) {
@Override
- public boolean acceptInput(VirtualFile file) {
+ public boolean acceptInput(@NotNull VirtualFile file) {
return !(file.getFileSystem() instanceof JarFileSystem);
}
};
diff --git a/xml/tests/src/com/intellij/codeInsight/completion/XmlTypedHandlersTest.java b/xml/tests/src/com/intellij/codeInsight/completion/XmlTypedHandlersTest.java
index 6c4b73f1789c..93967d26baea 100644
--- a/xml/tests/src/com/intellij/codeInsight/completion/XmlTypedHandlersTest.java
+++ b/xml/tests/src/com/intellij/codeInsight/completion/XmlTypedHandlersTest.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.codeInsight.completion;
import com.intellij.application.options.editor.WebEditorOptions;
import com.intellij.ide.highlighter.XmlFileType;
+import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
/**
@@ -24,16 +25,75 @@ import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCa
* Date: 30.08.13
*/
public class XmlTypedHandlersTest extends LightPlatformCodeInsightFixtureTestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ EditorTestUtil.enableMultipleCarets();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ EditorTestUtil.disableMultipleCarets();
+ super.tearDown();
+ }
- public void testClosingTag() throws Exception {
+ public void testClosingTag() {
doTest("<foo><<caret>", '/', "<foo></foo>");
}
+ public void testValueQuotesWithMultiCarets() {
+ doTest("<foo bar<caret>><foo bar<caret>>", '=', "<foo bar=\"<caret>\"><foo bar=\"<caret>\">");
+ }
+
+ public void testValueQuotesWithMultiCaretsWithDifferentContexts() {
+ doTest("<foo bar <caret>><foo bar<caret>>", '=', "<foo bar =<caret>><foo bar=\"<caret>\">");
+ }
+
+ public void testCloseTagOnSlashWithMultiCarets() {
+ doTest("<bar>\n" +
+ "<foo><<caret>\n" +
+ "<foo><<caret>\n" +
+ "</bar>", '/', "<bar>\n" +
+ "<foo></foo><caret>\n" +
+ "<foo></foo><caret>\n" +
+ "</bar>");
+ }
+
+ public void testCloseTagOnGtWithMultiCarets() {
+ doTest("<bar>\n" +
+ "<foo<caret>\n" +
+ "<foo<caret>\n" +
+ "</bar>", '>', "<bar>\n" +
+ "<foo><caret></foo>\n" +
+ "<foo><caret></foo>\n" +
+ "</bar>");
+ }
+
+ public void _testCloseTagOnSlashWithMultiCaretsInDifferentContexts() {
+ doTest("<bar>\n" +
+ "<foo><<caret>\n" +
+ "<fiz><<caret>\n" +
+ "</bar>", '/', "<bar>\n" +
+ "<foo></foo><caret>\n" +
+ "<fiz></fiz><caret>\n" +
+ "</bar>");
+ }
+
+ public void _testCloseTagOnGtWithMultiCaretsInDifferentContexts() {
+ doTest("<bar>\n" +
+ "<foo<caret>\n" +
+ "<fiz<caret>\n" +
+ "</bar>", '>', "<bar>\n" +
+ "<foo><caret></foo>\n" +
+ "<fiz><caret></fiz>\n" +
+ "</bar>");
+ }
+
public void testGreedyClosing() {
doTest("<foo><<caret>foo>", '/', "<foo></foo>");
}
- public void testValueQuotas() throws Exception {
+ public void testValueQuotas() {
doTest("<foo bar<caret>", '=', "<foo bar=\"<caret>\"");
WebEditorOptions.getInstance().setInsertQuotesForAttributeValue(false);
try {
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 4d58a5524bfe..d5bec52f6091 100644
--- a/xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java
@@ -514,18 +514,23 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx {
if (classLoader == null && clazz == null) return file;
final URL resource = clazz == null ? classLoader.getResource(file) : clazz.getResource(file);
- classLoader = null;
- clazz = null;
- if (resource == null) {
- String message = "Cannot find standard resource. filename:" + file + " class=" + classLoader;
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- LOG.error(message);
- }
- else {
- LOG.warn(message);
- }
- return null;
+ try {
+ if (resource == null) {
+ String message = "Cannot find standard resource. filename:" + file + " class=" + clazz + ", classLoader:" + classLoader;
+ if (ApplicationManager.getApplication().isUnitTestMode()) {
+ LOG.error(message);
+ }
+ else {
+ LOG.warn(message);
+ }
+
+ return null;
+ }
+ }
+ finally {
+ classLoader = null;
+ clazz = null;
}
String path = FileUtil.unquote(resource.toString());
@@ -535,7 +540,6 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx {
return path;
}
-
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/xml/xml-psi-impl/src/com/intellij/lang/html/HtmlParsing.java b/xml/xml-psi-impl/src/com/intellij/lang/html/HtmlParsing.java
index 250d27e9a101..55ab6d28fdd8 100644
--- a/xml/xml-psi-impl/src/com/intellij/lang/html/HtmlParsing.java
+++ b/xml/xml-psi-impl/src/com/intellij/lang/html/HtmlParsing.java
@@ -76,7 +76,10 @@ public class HtmlParsing {
error = flushError(error);
parseProcessingInstruction();
}
- else if (tt == XmlTokenType.XML_REAL_WHITE_SPACE || tt == XmlTokenType.XML_CHAR_ENTITY_REF || tt == XmlTokenType.XML_DATA_CHARACTERS) {
+ else if (tt == XmlTokenType.XML_CHAR_ENTITY_REF || tt == XmlTokenType.XML_ENTITY_REF_TOKEN) {
+ parseReference();
+ }
+ else if (tt == XmlTokenType.XML_REAL_WHITE_SPACE || tt == XmlTokenType.XML_DATA_CHARACTERS) {
error = flushError(error);
advance();
} else if (tt == XmlTokenType.XML_END_TAG_START) {
diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java
index e666cdcea090..8bd39976fe44 100644
--- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java
@@ -152,27 +152,28 @@ public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef {
) {
XmlDocument document = ((XmlFile)targetElement).getDocument();
final XmlTag rootTag = document.getRootTag();
+ XmlFile descriptorFile = null;
- if (rootTag != null && document.getUserData(DISABLE_ENTITY_EXPAND) == null) {
+ if (HtmlUtil.isHtml5Document(document)) {
+ descriptorFile = XmlUtil.findXmlFile((XmlFile)targetElement, Html5SchemaProvider.getCharsDtdLocation());
+ } else if (rootTag != null && document.getUserData(DISABLE_ENTITY_EXPAND) == null) {
final XmlElementDescriptor descriptor = rootTag.getDescriptor();
if (descriptor != null && !(descriptor instanceof AnyXmlElementDescriptor)) {
- PsiElement element = !HtmlUtil.isHtml5Context(rootTag) ? descriptor.getDeclaration() :
- XmlUtil.findXmlFile((XmlFile)targetElement, Html5SchemaProvider.getCharsDtdLocation());
+ PsiElement element = descriptor.getDeclaration();
final PsiFile containingFile = element != null ? element.getContainingFile():null;
- final XmlFile descriptorFile = containingFile instanceof XmlFile ? (XmlFile)containingFile:null;
-
- if (descriptorFile != null &&
- !descriptorFile.getName().equals(((XmlFile)targetElement).getName()+".dtd")) {
- deps.add(descriptorFile);
- XmlUtil.processXmlElements(
- descriptorFile,
- processor,
- true
- );
- }
+ descriptorFile = containingFile instanceof XmlFile ? (XmlFile)containingFile:null;
}
}
+ if (descriptorFile != null &&
+ !descriptorFile.getName().equals(((XmlFile)targetElement).getName() + ".dtd")) {
+ deps.add(descriptorFile);
+ XmlUtil.processXmlElements(
+ descriptorFile,
+ processor,
+ true
+ );
+ }
}
return new CachedValueProvider.Result<XmlEntityDecl>(result[0], ArrayUtil.toObjectArray(deps));
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java
index 36ae151d5964..5d35f0f4ae69 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java
@@ -325,7 +325,11 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
final CachedValue<XmlAttributeDescriptor> value = CachedValuesManager.getManager(includedDocument.getProject()).createCachedValue(
new CachedValueProvider<XmlAttributeDescriptor>(){
public Result<XmlAttributeDescriptor> compute() {
- return new Result<XmlAttributeDescriptor>(attributeDescriptor, attributeDescriptor.getDependences());
+ Object[] deps = attributeDescriptor.getDependences();
+ if (deps.length == 0) {
+ LOG.error(attributeDescriptor + " returned no dependencies");
+ }
+ return new Result<XmlAttributeDescriptor>(attributeDescriptor, deps);
}
},
false
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/index/XmlIndex.java b/xml/xml-psi-impl/src/com/intellij/xml/index/XmlIndex.java
index 1e549442011a..fb5242cb3e51 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/index/XmlIndex.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/index/XmlIndex.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.
@@ -95,13 +95,15 @@ public abstract class XmlIndex<V> extends FileBasedIndexExtension<String, V> {
};
}
+ @NotNull
public KeyDescriptor<String> getKeyDescriptor() {
return KEY_DESCRIPTOR;
}
+ @NotNull
public FileBasedIndex.InputFilter getInputFilter() {
return new DefaultFileTypeSpecificInputFilter(XmlFileType.INSTANCE, DTDFileType.INSTANCE) {
- public boolean acceptInput(final VirtualFile file) {
+ public boolean acceptInput(@NotNull final VirtualFile file) {
FileType fileType = file.getFileType();
final String extension = file.getExtension();
return XmlFileType.INSTANCE.equals(fileType) && "xsd".equals(extension) ||
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/index/XmlNamespaceIndex.java b/xml/xml-psi-impl/src/com/intellij/xml/index/XmlNamespaceIndex.java
index 55cde705430c..923a5cfce4e0 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/index/XmlNamespaceIndex.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/index/XmlNamespaceIndex.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.
@@ -107,11 +107,12 @@ public class XmlNamespaceIndex extends XmlIndex<XsdNamespaceBuilder> {
};
}
+ @NotNull
@Override
public DataExternalizer<XsdNamespaceBuilder> getValueExternalizer() {
return new DataExternalizer<XsdNamespaceBuilder>() {
@Override
- public void save(DataOutput out, XsdNamespaceBuilder value) throws IOException {
+ public void save(@NotNull DataOutput out, XsdNamespaceBuilder value) throws IOException {
out.writeUTF(value.getNamespace() == null ? "" : value.getNamespace());
out.writeUTF(value.getVersion() == null ? "" : value.getVersion());
out.writeInt(value.getTags().size());
@@ -121,7 +122,7 @@ public class XmlNamespaceIndex extends XmlIndex<XsdNamespaceBuilder> {
}
@Override
- public XsdNamespaceBuilder read(DataInput in) throws IOException {
+ public XsdNamespaceBuilder read(@NotNull DataInput in) throws IOException {
int count;
XsdNamespaceBuilder builder = new XsdNamespaceBuilder(in.readUTF(), in.readUTF(), new ArrayList<String>(count = in.readInt()));