summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/compiler/impl/compiler-impl.iml1
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java8
-rw-r--r--java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactUtil.java31
-rw-r--r--java/compiler/impl/src/org/jetbrains/builtInWebServer/ArtifactWebServerRootsProvider.java39
-rw-r--r--java/compiler/javac2/src/com/intellij/ant/Javac2.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/CustomizeContextViewAction.java28
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java30
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java19
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java7
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java23
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaValueMarker.java3
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java16
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java21
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java4
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java4
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java139
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/settings/DebuggerLaunchingConfigurable.java39
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.java59
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/settings/JavaDebuggerSettings.java59
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/settings/JavaHotSwapConfigurableUi.java (renamed from java/debugger/impl/src/com/intellij/debugger/settings/DebuggerHotswapConfigurable.java)45
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java130
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/DebuggerPanelsManager.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java38
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/AnyExceptionBreakpoint.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java17
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java10
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java5
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java8
-rw-r--r--java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java2
-rw-r--r--java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java9
-rw-r--r--java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java3
-rw-r--r--java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java1
-rw-r--r--java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java4
-rw-r--r--java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java2
-rw-r--r--java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.java57
-rw-r--r--java/idea-ui/src/com/intellij/openapi/projectRoots/ui/SdkEditor.java11
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java4
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.form8
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectConfigurable.java8
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java5
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java6
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java13
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java21
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsEditorImpl.form2
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java20
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTreeComponent.java5
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java6
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java3
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java9
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetsTreeCellRenderer.java12
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java7
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java26
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java17
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java8
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java14
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Analysis.java5
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java359
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverterImpl.java206
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java166
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java19
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Contracts.java2
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Parameters.java19
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ProjectBytecodeAnalysis.java260
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java152
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java21
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/MethodContract.java14
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java10
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/xml/DeprecatedClassUsageInspection.java8
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodQualifierFix.java11
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AnonymousTargetClassPreselectionUtil.java45
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java9
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java11
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCatchBodyFixer.java5
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java20
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java16
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java12
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastExpressionPostfixTemplate.java10
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceFieldPostfixTemplate.java10
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceVariablePostfixTemplate.java10
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateWithChooser.java42
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java16
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedExpressionPostfixTemplate.java12
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/postfix/util/JavaPostfixTemplatesUtils.java10
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java10
-rw-r--r--java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java34
-rw-r--r--java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java24
-rw-r--r--java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java34
-rw-r--r--java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java1
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java3
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FilePathReferenceProvider.java2
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/MethodPropertyReference.java5
-rw-r--r--java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java29
-rw-r--r--java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java6
-rw-r--r--java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java10
-rw-r--r--java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java8
-rw-r--r--java/java-impl/src/com/intellij/refactoring/rename/RenameJavaMethodProcessor.java14
-rw-r--r--java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java2
-rw-r--r--java/java-impl/src/com/intellij/testIntegration/createTest/MissedTestsDialog.java26
-rw-r--r--java/java-impl/src/com/intellij/usages/impl/rules/JavaUsageTypeProvider.java3
-rw-r--r--java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java136
-rw-r--r--java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java4
-rw-r--r--java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java72
-rw-r--r--java/java-psi-api/src/com/intellij/psi/GenericsUtil.java3
-rw-r--r--java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java8
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java10
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java5
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java499
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/CustomExceptionHandler.java13
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java5
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java8
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/ParameterNameFoldingManager.java6
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/javadoc/ColorUtil.java14
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java22
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/InheritanceImplUtil.java102
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java132
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java8
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java49
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java50
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java5
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java29
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java9
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java8
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java10
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java38
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationParamListElement.java111
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java52
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterListElement.java56
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationParamListImpl.java26
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java69
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCommaSeparatedListImpl.java85
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java21
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java46
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java37
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java37
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java15
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java2
-rw-r--r--java/java-structure-view/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java6
-rw-r--r--java/java-tests/testData/codeInsight/clsHighlighting/IDEA127714.java9
-rw-r--r--java/java-tests/testData/codeInsight/clsHighlighting/libs/IDEA127714.jarbin0 -> 1972 bytes
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/AlreadyCompleteCatch.java12
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/AlreadyCompleteCatch_after.java12
-rw-r--r--java/java-tests/testData/codeInsight/completion/normal/MulticaretCompletionFromNonPrimaryCaret.java4
-rw-r--r--java/java-tests/testData/codeInsight/completion/smartType/DontSuggestWildcardGenerics-out.java16
-rw-r--r--java/java-tests/testData/codeInsight/completion/smartType/DontSuggestWildcardGenerics.java11
-rw-r--r--java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferFieldsToConstants.java17
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/PolymorphicTypeCast.java92
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128101.java29
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128174.java24
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/InferFromConditionalExpressionCondition.java14
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/PrimitiveWrapperConditionInReturnConstraint.java15
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/EffectiveFinal.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/IDEA127765.java19
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterOnVarargsPlace.java10
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeOnVarargsPlace.java13
-rw-r--r--java/java-tests/testData/codeInsight/template/postfix/templates/null/singleExclamationIgnored.java5
-rw-r--r--java/java-tests/testData/codeInsight/template/postfix/templates/null/singleExclamationIgnored_after.java5
-rw-r--r--java/java-tests/testData/codeInsight/typing/invalidInitialSyntax_after.java7
-rw-r--r--java/java-tests/testData/codeInsight/typing/invalidInitialSyntax_before.java7
-rw-r--r--java/java-tests/testData/find/findInEditor/BasicFind.gold4
-rw-r--r--java/java-tests/testData/find/findInEditor/EmacsLikeFallback.gold12
-rw-r--r--java/java-tests/testData/find/findInEditor/ReplacementWithEmptyString.gold16
-rw-r--r--java/java-tests/testData/inspection/dataFlow/CheckedExceptionDominance/src/Test.java2
-rw-r--r--java/java-tests/testData/inspection/dataFlow/IDEADEV10489/expected.xml2
-rw-r--r--java/java-tests/testData/inspection/dataFlow/IDEADEV10489/src/IDEADEV10489.java8
-rw-r--r--java/java-tests/testData/inspection/dataFlow/fixture/AssertFailInCatch.java4
-rw-r--r--java/java-tests/testData/inspection/dataFlow/fixture/CatchThrowable.java4
-rw-r--r--java/java-tests/testData/inspection/dataFlow/fixture/ContractWithNoArgs.java24
-rw-r--r--java/java-tests/testData/inspection/dataFlow/fixture/CustomTypeQualifierDefault.java25
-rw-r--r--java/java-tests/testData/inspection/dataFlow/fixture/FloatComparisons.java7
-rw-r--r--java/java-tests/testData/refactoring/renameCollisions/RenameMethodNoCollisionWithOtherSignatureMethodRef.java9
-rw-r--r--java/java-tests/testData/refactoring/renameCollisions/RenameMethodNoCollisionWithOtherSignatureMethodRef.java.after9
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/ClsGenerics18HighlightingTest.java2
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java17
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java9
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy5
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy4
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java6
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java16
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java4
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingGotoTest.java59
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy16
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/NullPostfixTemplateTest.java5
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy28
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java38
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java11
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisTest.java4
-rw-r--r--java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java28
-rw-r--r--java/java-tests/testSrc/com/intellij/find/FindManagerTest.java47
-rw-r--r--java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy28
-rw-r--r--java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java198
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java16
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy24
-rw-r--r--java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java4
-rw-r--r--java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java31
-rw-r--r--java/java-tests/testSrc/com/intellij/slicer/SliceTreeTest.java3
-rw-r--r--java/jsp-openapi/src/com/intellij/psi/jsp/JavaJspElementVisitor.java3
-rw-r--r--java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java17
-rw-r--r--java/remote-servers/impl/remote-servers-java-impl.iml1
-rw-r--r--java/remote-servers/impl/src/META-INF/RemoteServersJava.xml2
-rw-r--r--java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfigurable.java142
-rw-r--r--java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfiguration.java15
-rw-r--r--java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java64
-rw-r--r--java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContribution.java48
-rw-r--r--java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionBase.java142
-rw-r--r--java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionFactory.java39
-rw-r--r--java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderSourceContribution.java191
-rw-r--r--java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.java25
-rw-r--r--java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfigurable.java165
-rw-r--r--java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfiguration.java (renamed from java/jsp-openapi/src/com/intellij/psi/jsp/JspImplicitVariable.java)32
-rw-r--r--java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java29
-rw-r--r--java/testFramework/src/com/intellij/find/FindManagerTestUtils.java6
221 files changed, 3973 insertions, 2608 deletions
diff --git a/java/compiler/impl/compiler-impl.iml b/java/compiler/impl/compiler-impl.iml
index 08d3ca179fc0..c6e3e4f81eab 100644
--- a/java/compiler/impl/compiler-impl.iml
+++ b/java/compiler/impl/compiler-impl.iml
@@ -28,6 +28,7 @@
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
<orderEntry type="module" module-name="jps-model-impl" />
<orderEntry type="module" module-name="java-analysis-impl" />
+ <orderEntry type="module" module-name="xml" />
</component>
<component name="copyright">
<Base>
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 03ff006eea40..01da3bc62541 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
@@ -128,8 +128,6 @@ public class BuildManager implements ApplicationComponent{
private static final String COMPILER_PROCESS_JDK_PROPERTY = "compiler.process.jdk";
public static final String SYSTEM_ROOT = "compile-server";
public static final String TEMP_DIR_NAME = "_temp_";
- private static final int MAKE_TRIGGER_DELAY = 300 /*300 ms*/;
- private static final int DOCUMENT_SAVE_TRIGGER_DELAY = 1500 /*1.5 sec*/;
private final boolean IS_UNIT_TEST_MODE;
private static final String IWS_EXTENSION = ".iws";
private static final String IPR_EXTENSION = ".ipr";
@@ -161,7 +159,7 @@ public class BuildManager implements ApplicationComponent{
private final BuildManagerPeriodicTask myAutoMakeTask = new BuildManagerPeriodicTask() {
@Override
protected int getDelay() {
- return Registry.intValue("compiler.automake.trigger.delay", MAKE_TRIGGER_DELAY);
+ return Registry.intValue("compiler.automake.trigger.delay");
}
@Override
@@ -173,7 +171,7 @@ public class BuildManager implements ApplicationComponent{
private final BuildManagerPeriodicTask myDocumentSaveTask = new BuildManagerPeriodicTask() {
@Override
protected int getDelay() {
- return Registry.intValue("compiler.document.save.trigger.delay", DOCUMENT_SAVE_TRIGGER_DELAY);
+ return Registry.intValue("compiler.document.save.trigger.delay");
}
private final Semaphore mySemaphore = new Semaphore();
@@ -624,7 +622,7 @@ public class BuildManager implements ApplicationComponent{
data = new ProjectData(new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE));
myProjectDataMap.put(projectPath, data);
}
- if (isRebuild || (isAutomake && Registry.is("compiler.automake.force.fs.rescan", false))) {
+ if (isRebuild || (isAutomake && Registry.is("compiler.automake.force.fs.rescan"))) {
data.dropChanges();
}
if (IS_UNIT_TEST_MODE) {
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactUtil.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactUtil.java
index 5752c3f5f77b..3fcfc8df5529 100644
--- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactUtil.java
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactUtil.java
@@ -26,10 +26,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.packaging.artifacts.Artifact;
-import com.intellij.packaging.artifacts.ArtifactManager;
-import com.intellij.packaging.artifacts.ArtifactProperties;
-import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.artifacts.*;
import com.intellij.packaging.elements.*;
import com.intellij.packaging.impl.elements.*;
import com.intellij.util.PathUtil;
@@ -599,5 +596,31 @@ public class ArtifactUtil {
public static String suggestArtifactFileName(String artifactName) {
return PathUtil.suggestFileName(artifactName, true, true);
}
+
+ @Nullable
+ public static Artifact addArtifact(@NotNull ModifiableArtifactModel artifactModel,
+ @NotNull ArtifactType type,
+ @NotNull ArtifactTemplate artifactTemplate) {
+ final ArtifactTemplate.NewArtifactConfiguration configuration = artifactTemplate.createArtifact();
+ if (configuration == null) {
+ return null;
+ }
+
+ final String baseName = configuration.getArtifactName();
+ String name = baseName;
+ int i = 2;
+ while (artifactModel.findArtifact(name) != null) {
+ name = baseName + i;
+ i++;
+ }
+
+ ArtifactType actualType = configuration.getArtifactType();
+ if (actualType == null) {
+ actualType = type;
+ }
+ final ModifiableArtifact artifact = artifactModel.addArtifact(name, actualType, configuration.getRootElement());
+ artifactTemplate.setUpArtifact(artifact, configuration);
+ return artifact;
+ }
}
diff --git a/java/compiler/impl/src/org/jetbrains/builtInWebServer/ArtifactWebServerRootsProvider.java b/java/compiler/impl/src/org/jetbrains/builtInWebServer/ArtifactWebServerRootsProvider.java
new file mode 100644
index 000000000000..4733ca3747ec
--- /dev/null
+++ b/java/compiler/impl/src/org/jetbrains/builtInWebServer/ArtifactWebServerRootsProvider.java
@@ -0,0 +1,39 @@
+package org.jetbrains.builtInWebServer;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.util.PairFunction;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+final class ArtifactWebServerRootsProvider extends PrefixlessWebServerRootsProvider {
+ @Nullable
+ @Override
+ public PathInfo resolve(@NotNull String path, @NotNull Project project, @NotNull PairFunction<String, VirtualFile, VirtualFile> resolver) {
+ for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) {
+ VirtualFile root = artifact.getOutputFile();
+ if (root != null) {
+ VirtualFile file = root.findFileByRelativePath(path);
+ if (file != null) {
+ return new PathInfo(file, root);
+ }
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public PathInfo getRoot(@NotNull VirtualFile file, @NotNull Project project) {
+ for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) {
+ VirtualFile root = artifact.getOutputFile();
+ if (root != null && VfsUtilCore.isAncestor(root, file, true)) {
+ return new PathInfo(file, root);
+ }
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/java/compiler/javac2/src/com/intellij/ant/Javac2.java b/java/compiler/javac2/src/com/intellij/ant/Javac2.java
index 88095a9cdc36..e5b8aee7130a 100644
--- a/java/compiler/javac2/src/com/intellij/ant/Javac2.java
+++ b/java/compiler/javac2/src/com/intellij/ant/Javac2.java
@@ -466,7 +466,7 @@ public class Javac2 extends Javac {
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
classfileVersion[0] = version;
}
- }, 0);
+ }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
return classfileVersion[0];
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/CustomizeContextViewAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/CustomizeContextViewAction.java
index 01d6fcc6e7e8..6214a9e44d7f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/CustomizeContextViewAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/CustomizeContextViewAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,14 +17,12 @@ package com.intellij.debugger.actions;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.engine.JavaDebugProcess;
-import com.intellij.debugger.settings.DebuggerDataViewsConfigurable;
+import com.intellij.debugger.settings.JavaDebuggerSettings;
import com.intellij.debugger.settings.NodeRendererSettings;
-import com.intellij.debugger.settings.UserRenderersConfigurable;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.options.CompositeConfigurable;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.TabbedConfigurable;
@@ -40,16 +38,9 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
-import java.util.ArrayList;
import java.util.List;
-/**
- * User: lex
- * Date: Sep 26, 2003
- * Time: 4:39:53 PM
- */
public class CustomizeContextViewAction extends XDebuggerTreeActionBase {
-
@Override
public void actionPerformed(AnActionEvent e) {
perform(null, "", e);
@@ -58,15 +49,11 @@ public class CustomizeContextViewAction extends XDebuggerTreeActionBase {
@Override
protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) {
final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
-
Disposable disposable = Disposer.newDisposable();
- final CompositeConfigurable configurable = new TabbedConfigurable(disposable) {
+ SingleConfigurableEditor editor = new SingleConfigurableEditor(project, new TabbedConfigurable(disposable) {
@Override
protected List<Configurable> createConfigurables() {
- ArrayList<Configurable> array = new ArrayList<Configurable>();
- array.add(new DebuggerDataViewsConfigurable(project));
- array.add(new UserRenderersConfigurable(project));
- return array;
+ return JavaDebuggerSettings.createDataViewsConfigurable();
}
@Override
@@ -89,13 +76,12 @@ public class CustomizeContextViewAction extends XDebuggerTreeActionBase {
protected void createConfigurableTabs() {
for (Configurable configurable : getConfigurables()) {
JComponent component = configurable.createComponent();
- component.setBorder(new EmptyBorder(8,8,8,8));
+ assert component != null;
+ component.setBorder(new EmptyBorder(8, 8, 8, 8));
myTabbedPane.addTab(configurable.getDisplayName(), component);
}
}
- };
-
- SingleConfigurableEditor editor = new SingleConfigurableEditor(project, configurable);
+ });
Disposer.register(editor.getDisposable(), disposable);
editor.show();
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java
index 1db0ed60774e..4714ca49bd06 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java
@@ -322,10 +322,15 @@ public class DebugProcessEvents extends DebugProcessImpl {
myDebugProcessDispatcher.getMulticaster().processAttached(this);
// breakpoints should be initialized after all processAttached listeners work
- XDebugSession session = getSession().getXDebugSession();
- if (session != null) {
- session.initBreakpoints();
- }
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ XDebugSession session = getSession().getXDebugSession();
+ if (session != null) {
+ session.initBreakpoints();
+ }
+ }
+ });
final String addressDisplayName = DebuggerBundle.getAddressDisplayName(getConnection());
final String transportName = DebuggerBundle.getTransportName(getConnection());
@@ -459,13 +464,18 @@ public class DebugProcessEvents extends DebugProcessImpl {
if (requestHit && requestor instanceof Breakpoint) {
// if requestor is a breakpoint and this breakpoint was hit, no matter its suspend policy
- XDebugSession session = getSession().getXDebugSession();
- if (session != null) {
- XBreakpoint breakpoint = ((Breakpoint)requestor).getXBreakpoint();
- if (breakpoint != null) {
- ((XDebugSessionImpl)session).processDependencies(breakpoint);
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ XDebugSession session = getSession().getXDebugSession();
+ if (session != null) {
+ XBreakpoint breakpoint = ((Breakpoint)requestor).getXBreakpoint();
+ if (breakpoint != null) {
+ ((XDebugSessionImpl)session).processDependencies(breakpoint);
+ }
+ }
}
- }
+ });
}
if(!requestHit || resumePreferred) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java
index ad2c881d1336..75897417bd2e 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java
@@ -49,13 +49,17 @@ public class JavaBreakpointHandler extends XBreakpointHandler {
if (javaBreakpoint != null) {
final Breakpoint bpt = javaBreakpoint;
BreakpointManager.addBreakpoint(bpt);
- // must use invoke to stay in the current request,
- // otherwise dependent breakpoints do not get enabled on not-suspending parents hit
- myProcess.getManagerThread().invoke(new DebuggerCommandImpl() {
+ // use schedule not to block initBreakpoints
+ myProcess.getManagerThread().schedule(new DebuggerCommandImpl() {
@Override
protected void action() throws Exception {
bpt.createRequest(myProcess);
}
+
+ @Override
+ public Priority getPriority() {
+ return Priority.HIGH;
+ }
});
}
}
@@ -64,12 +68,17 @@ public class JavaBreakpointHandler extends XBreakpointHandler {
public void unregisterBreakpoint(@NotNull final XBreakpoint breakpoint, boolean temporary) {
final Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint(breakpoint);
if (javaBreakpoint != null) {
- // must use invoke to stay in the current request, see comment in registerBreakpoint
- myProcess.getManagerThread().invoke(new DebuggerCommandImpl() {
+ // use schedule not to block initBreakpoints
+ myProcess.getManagerThread().schedule(new DebuggerCommandImpl() {
@Override
protected void action() throws Exception {
javaBreakpoint.delete();
}
+
+ @Override
+ public Priority getPriority() {
+ return Priority.HIGH;
+ }
});
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java
index 793438ebbe05..f2cb40008ad5 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java
@@ -26,6 +26,7 @@ import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.debugger.ui.impl.watch.MethodsTracker;
+import com.intellij.debugger.ui.impl.watch.NodeManagerImpl;
import com.intellij.icons.AllIcons;
import com.intellij.xdebugger.frame.XExecutionStack;
import com.sun.jdi.ThreadReference;
@@ -43,6 +44,7 @@ import java.util.Iterator;
public class JavaExecutionStack extends XExecutionStack {
private final ThreadReferenceProxyImpl myThreadProxy;
private final DebugProcessImpl myDebugProcess;
+ private final NodeManagerImpl myNodeManager;
private volatile JavaStackFrame myTopFrame;
private boolean myTopFrameReady = false;
private final MethodsTracker myTracker = new MethodsTracker();
@@ -51,6 +53,7 @@ public class JavaExecutionStack extends XExecutionStack {
super(calcRepresentation(threadProxy), calcIcon(threadProxy, current));
myThreadProxy = threadProxy;
myDebugProcess = debugProcess;
+ myNodeManager = myDebugProcess.getXdebugProcess().getNodeManager();
if (current) {
myTopFrame = calcTopFrame();
}
@@ -81,7 +84,7 @@ public class JavaExecutionStack extends XExecutionStack {
try {
StackFrameProxyImpl frame = myThreadProxy.frame(0);
if (frame != null) {
- return new JavaStackFrame(frame, myDebugProcess, myTracker);
+ return new JavaStackFrame(frame, myDebugProcess, myTracker, myNodeManager);
}
}
catch (EvaluateException e) {
@@ -180,7 +183,7 @@ public class JavaExecutionStack extends XExecutionStack {
@Override
public void contextAction() throws Exception {
if (myStackFramesIterator.hasNext()) {
- JavaStackFrame frame = new JavaStackFrame(myStackFramesIterator.next(), myDebugProcess, myTracker);
+ JavaStackFrame frame = new JavaStackFrame(myStackFramesIterator.next(), myDebugProcess, myTracker, myNodeManager);
if (DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES || (!frame.getDescriptor().isSynthetic() && !frame.getDescriptor().isInLibraryContent())) {
if (++myAdded > mySkip) {
myContainer.addStackFrames(Arrays.asList(frame), false);
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
index bcd8257736c2..db28c4bf34a7 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
@@ -71,9 +71,12 @@ public class JavaStackFrame extends XStackFrame {
private static final JavaFramesListRenderer FRAME_RENDERER = new JavaFramesListRenderer();
private JavaDebuggerEvaluator myEvaluator = null;
- public JavaStackFrame(@NotNull StackFrameProxyImpl stackFrameProxy, @NotNull DebugProcessImpl debugProcess, MethodsTracker tracker) {
+ public JavaStackFrame(@NotNull StackFrameProxyImpl stackFrameProxy,
+ @NotNull DebugProcessImpl debugProcess,
+ @NotNull MethodsTracker tracker,
+ @NotNull NodeManagerImpl nodeManager) {
myDebugProcess = debugProcess;
- myNodeManager = debugProcess.getXdebugProcess().getNodeManager();
+ myNodeManager = nodeManager;
myDescriptor = new StackFrameDescriptorImpl(stackFrameProxy, tracker);
myDescriptor.setContext(null);
myDescriptor.updateRepresentation(null, DescriptorLabelListener.DUMMY_LISTENER);
@@ -311,8 +314,7 @@ public class JavaStackFrame extends XStackFrame {
final Collection<Value> argValues = frame.getArgumentValues();
int index = 0;
for (Value argValue : argValues) {
- final ArgumentValueDescriptorImpl descriptor = myNodeManager.getArgumentValueDescriptor(null, index++, argValue, null);
- children.add(JavaValue.create(descriptor, evaluationContext, myNodeManager));
+ children.add(createArgumentValue(index++, argValue, null, evaluationContext));
}
node.setMessage(MessageDescriptor.LOCAL_VARIABLES_INFO_UNAVAILABLE.getLabel(), XDebuggerUIConstants.INFORMATION_MESSAGE_ICON, SimpleTextAttributes.REGULAR_ATTRIBUTES, null);
//myChildren.add(myNodeManager.createMessageNode(MessageDescriptor.LOCAL_VARIABLES_INFO_UNAVAILABLE));
@@ -323,9 +325,7 @@ public class JavaStackFrame extends XStackFrame {
try {
final Map<DecompiledLocalVariable, Value> values = LocalVariablesUtil.fetchValues(frame.getStackFrame(), decompiled);
for (DecompiledLocalVariable var : decompiled) {
- final Value value = values.get(var);
- final ArgumentValueDescriptorImpl descriptor = myNodeManager.getArgumentValueDescriptor(null, var.getSlot(), value, var.getName());
- children.add(JavaValue.create(descriptor, evaluationContext, myNodeManager));
+ children.add(createArgumentValue(var.getSlot(), values.get(var), var.getName(), evaluationContext));
}
}
catch (Exception ex) {
@@ -339,6 +339,13 @@ public class JavaStackFrame extends XStackFrame {
}
}
+ private JavaValue createArgumentValue(int index, Value value, String name, EvaluationContextImpl evaluationContext) {
+ ArgumentValueDescriptorImpl descriptor = myNodeManager.getArgumentValueDescriptor(null, index, value, name);
+ // setContext is required to calculate correct name
+ descriptor.setContext(evaluationContext);
+ return JavaValue.create(descriptor, evaluationContext, myNodeManager);
+ }
+
protected void superBuildVariables(final EvaluationContextImpl evaluationContext, XValueChildrenList children) throws EvaluateException {
final StackFrameProxyImpl frame = getStackFrameProxy();
for (final LocalVariableProxyImpl local : frame.visibleVariables()) {
@@ -354,6 +361,6 @@ public class JavaStackFrame extends XStackFrame {
@Nullable
@Override
public Object getEqualityObject() {
- return getStackFrameProxy().hashCode();
+ return myDescriptor.getMethod();
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueMarker.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueMarker.java
index be1b8fae60b9..6a555a87063a 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueMarker.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueMarker.java
@@ -30,8 +30,7 @@ public class JavaValueMarker extends XValueMarkerProvider<JavaValue, ObjectRefer
@Override
public boolean canMark(@NotNull JavaValue value) {
- Value obj = value.getDescriptor().getValue();
- return obj instanceof ObjectReference;
+ return value.getDescriptor().canMark();
}
@Override
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java
index 576f781dc368..c1f1f87db1a9 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java
@@ -15,6 +15,7 @@
*/
package com.intellij.debugger.engine;
+import com.intellij.debugger.engine.events.DebuggerCommandImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.sun.jdi.InternalException;
@@ -296,7 +297,7 @@ public class SuspendManagerImpl implements SuspendManager {
}
}
- private void processVote(SuspendContextImpl suspendContext) {
+ private void processVote(final SuspendContextImpl suspendContext) {
LOG.assertTrue(suspendContext.myVotesToVote > 0);
suspendContext.myVotesToVote--;
@@ -305,7 +306,18 @@ public class SuspendManagerImpl implements SuspendManager {
}
if(suspendContext.myVotesToVote == 0) {
if(suspendContext.myIsVotedForResume) {
- resume(suspendContext);
+ // resume in a separate request to allow other requests be processed (e.g. dependent bpts enable)
+ myDebugProcess.getManagerThread().schedule(new DebuggerCommandImpl() {
+ @Override
+ protected void action() throws Exception {
+ resume(suspendContext);
+ }
+
+ @Override
+ public Priority getPriority() {
+ return Priority.HIGH;
+ }
+ });
}
else {
if (LOG.isDebugEnabled()) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java
index 69cbb140be86..2569559d2d11 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java
@@ -30,7 +30,10 @@ import com.intellij.debugger.engine.evaluation.EvaluateRuntimeException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.openapi.diagnostic.Logger;
-import com.sun.jdi.*;
+import com.sun.jdi.ClassType;
+import com.sun.jdi.Method;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ReferenceType;
import java.util.ArrayList;
import java.util.List;
@@ -127,14 +130,16 @@ public class MethodEvaluator implements Evaluator {
_refType = ((ClassType)referenceType).superclass();
}
Method jdiMethod = DebuggerUtils.findMethod(_refType, myMethodName, signature);
- if (jdiMethod == null || jdiMethod.argumentTypes().size() != args.size()) {
+ if (signature == null) {
+ // we know nothing about expected method's signature, so trying to match my method name and parameter count
// dummy matching, may be improved with types matching later
- List<Method> methods = _refType.methodsByName(myMethodName);
- for (Method method : methods) {
- List<Type> types = method.argumentTypes();
- if (types.size() == args.size()) {
- jdiMethod = method;
- break;
+ // IMPORTANT! using argumentTypeNames() instead of argumentTypes() to avoid type resolution inside JDI, which may be time-consuming
+ if (jdiMethod == null || jdiMethod.argumentTypeNames().size() != args.size()) {
+ for (Method method : _refType.methodsByName(myMethodName)) {
+ if (method.argumentTypeNames().size() == args.size()) {
+ jdiMethod = method;
+ break;
+ }
}
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java
index f5404cd65023..79c1db31db3c 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java
@@ -28,6 +28,7 @@ import com.intellij.execution.configurations.JavaParameters;
import com.intellij.execution.configurations.ModuleRunProfile;
import com.intellij.execution.configurations.RemoteConnection;
import com.intellij.execution.configurations.RunProfileState;
+import com.intellij.execution.process.KillableColoredProcessHandler;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessHandler;
@@ -286,7 +287,8 @@ public class DebuggerManagerImpl extends DebuggerManagerEx implements Persistent
final DebugProcessImpl debugProcess = getDebugProcess(event.getProcessHandler());
if (debugProcess != null) {
// if current thread is a "debugger manager thread", stop will execute synchronously
- debugProcess.stop(willBeDestroyed);
+ // it is KillableColoredProcessHandler responsibility to terminate VM
+ debugProcess.stop(willBeDestroyed && !(event.getProcessHandler() instanceof KillableColoredProcessHandler));
// wait at most 10 seconds: the problem is that debugProcess.stop() can hang if there are troubles in the debuggee
// if processWillTerminate() is called from AWT thread debugProcess.waitFor() will block it and the whole app will hang
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java
index 7b76b9738843..02f4ee44fd53 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java
@@ -110,7 +110,9 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider {
else if (parent instanceof PsiInstanceOfExpression
|| parent instanceof PsiBinaryExpression
|| parent instanceof PsiPolyadicExpression
- || parent instanceof PsiPrefixExpression) {
+ || parent instanceof PsiPrefixExpression
+ || parent instanceof PsiConditionalExpression
+ ) {
if (allowMethodCalls || !DebuggerUtils.hasSideEffects(parent)) {
expression = parent;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java
index e570b642b2bd..a4484cccc1fe 100644
--- a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java
+++ b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java
@@ -25,14 +25,10 @@ import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.ui.DebuggerExpressionTextField;
import com.intellij.debugger.ui.JavaDebuggerSupport;
import com.intellij.debugger.ui.tree.render.*;
-import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
@@ -41,7 +37,7 @@ import com.intellij.ui.table.JBTable;
import com.intellij.util.Function;
import com.intellij.util.ui.AbstractTableCellEditor;
import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
@@ -52,57 +48,33 @@ import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
-/**
- * @author Eugene Zhuravlev
- * Date: Feb 24, 2005
- */
-public class CompoundRendererConfigurable implements UnnamedConfigurable {
+class CompoundRendererConfigurable extends JPanel {
private CompoundReferenceRenderer myRenderer;
private CompoundReferenceRenderer myOriginalRenderer;
private Project myProject;
- private ClassNameEditorWithBrowseButton myClassNameField;
- private JRadioButton myRbDefaultLabel;
- private JRadioButton myRbExpressionLabel;
- private JRadioButton myRbDefaultChildrenRenderer;
- private JRadioButton myRbExpressionChildrenRenderer;
- private JRadioButton myRbListChildrenRenderer;
- private DebuggerExpressionTextField myLabelEditor;
- private DebuggerExpressionTextField myChildrenEditor;
- private DebuggerExpressionTextField myChildrenExpandedEditor;
+ private final ClassNameEditorWithBrowseButton myClassNameField;
+ private final JRadioButton myRbDefaultLabel;
+ private final JRadioButton myRbExpressionLabel;
+ private final JRadioButton myRbDefaultChildrenRenderer;
+ private final JRadioButton myRbExpressionChildrenRenderer;
+ private final JRadioButton myRbListChildrenRenderer;
+ private final DebuggerExpressionTextField myLabelEditor;
+ private final DebuggerExpressionTextField myChildrenEditor;
+ private final DebuggerExpressionTextField myChildrenExpandedEditor;
private DebuggerExpressionTextField myListChildrenEditor;
- private JComponent myChildrenListEditor;
- private JLabel myExpandedLabel;
- private JPanel myMainPanel;
+ private final JLabel myExpandedLabel;
private JBTable myTable;
@NonNls private static final String EMPTY_PANEL_ID = "EMPTY";
@NonNls private static final String DATA_PANEL_ID = "DATA";
private static final int NAME_TABLE_COLUMN = 0;
private static final int EXPRESSION_TABLE_COLUMN = 1;
- public CompoundRendererConfigurable(@Nullable Project project) {
- myProject = project;
- }
-
- public void setRenderer(NodeRenderer renderer) {
- if (renderer instanceof CompoundReferenceRenderer) {
- myRenderer = (CompoundReferenceRenderer)renderer;
- myOriginalRenderer = (CompoundReferenceRenderer)renderer.clone();
- }
- else {
- myRenderer = myOriginalRenderer = null;
- }
- reset();
- }
-
- public CompoundReferenceRenderer getRenderer() {
- return myRenderer;
- }
+ public CompoundRendererConfigurable() {
+ super(new CardLayout());
- public JComponent createComponent() {
if (myProject == null) {
myProject = JavaDebuggerSupport.getContextProjectForEditorFieldsInDebuggerConfigurables();
}
- final JPanel panel = new JPanel(new GridBagLayout());
myRbDefaultLabel = new JRadioButton(DebuggerBundle.message("label.compound.renderer.configurable.use.default.renderer"));
myRbExpressionLabel = new JRadioButton(DebuggerBundle.message("label.compound.renderer.configurable.use.expression"));
@@ -121,10 +93,11 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
myLabelEditor = new DebuggerExpressionTextField(myProject, null, "ClassLabelExpression");
myChildrenEditor = new DebuggerExpressionTextField(myProject, null, "ClassChildrenExpression");
myChildrenExpandedEditor = new DebuggerExpressionTextField(myProject, null, "ClassChildrenExpression");
- myChildrenListEditor = createChildrenListEditor();
+ JComponent myChildrenListEditor = createChildrenListEditor();
final ItemListener updateListener = new ItemListener() {
- public void itemStateChanged(ItemEvent e) {
+ @Override
+ public void itemStateChanged(@NotNull ItemEvent e) {
updateEnabledState();
}
};
@@ -133,7 +106,8 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
myRbExpressionChildrenRenderer.addItemListener(updateListener);
myClassNameField = new ClassNameEditorWithBrowseButton(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
PsiClass psiClass = DebuggerUtils.getInstance()
.chooseClassDialog(DebuggerBundle.message("title.compound.renderer.configurable.choose.renderer.reference.type"), myProject);
if (psiClass != null) {
@@ -143,20 +117,14 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
}
}
}, myProject);
- final EditorTextField textField = myClassNameField.getEditorTextField();
- final FocusAdapter updateContextListener = new FocusAdapter() {
- public void focusLost(FocusEvent e) {
- updateContext(myClassNameField.getText());
- }
- };
- textField.addFocusListener(updateContextListener);
- Disposer.register(myClassNameField, new Disposable() {
+ myClassNameField.getEditorTextField().addFocusListener(new FocusAdapter() {
@Override
- public void dispose() {
- textField.removeFocusListener(updateContextListener);
+ public void focusLost(@NotNull FocusEvent e) {
+ updateContext(myClassNameField.getText());
}
});
+ JPanel panel = new JPanel(new GridBagLayout());
panel.add(new JLabel(DebuggerBundle.message("label.compound.renderer.configurable.apply.to")),
new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0));
@@ -197,15 +165,28 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
panel.add(myChildrenListEditor,
new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
new Insets(4, 30, 0, 0), 0, 0));
+ add(new JPanel(), EMPTY_PANEL_ID);
+ add(panel, DATA_PANEL_ID);
+ }
- myMainPanel = new JPanel(new CardLayout());
- myMainPanel.add(new JPanel(), EMPTY_PANEL_ID);
- myMainPanel.add(panel, DATA_PANEL_ID);
- return myMainPanel;
+ public void setRenderer(NodeRenderer renderer) {
+ if (renderer instanceof CompoundReferenceRenderer) {
+ myRenderer = (CompoundReferenceRenderer)renderer;
+ myOriginalRenderer = (CompoundReferenceRenderer)renderer.clone();
+ }
+ else {
+ myRenderer = myOriginalRenderer = null;
+ }
+ reset();
+ }
+
+ public CompoundReferenceRenderer getRenderer() {
+ return myRenderer;
}
private void updateContext(final String qName) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
public void run() {
final Project project = myProject;
final PsiClass psiClass = project != null ? DebuggerUtils.findClass(qName, project, GlobalSearchScope.allScope(project)) : null;
@@ -214,6 +195,7 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
myChildrenExpandedEditor.setContext(psiClass);
myListChildrenEditor.setContext(psiClass);
+ assert project != null;
PsiType type = DebuggerUtils.getType(qName, project);
myLabelEditor.setThisType(type);
myChildrenEditor.setThisType(type);
@@ -251,17 +233,21 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
final TableColumn exprColumn = myTable.getColumnModel().getColumn(EXPRESSION_TABLE_COLUMN);
exprColumn.setCellEditor(new AbstractTableCellEditor() {
+ @Override
public Object getCellEditorValue() {
return myListChildrenEditor.getText();
}
+ @Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
myListChildrenEditor.setText((TextWithImports)value);
return myListChildrenEditor;
}
});
exprColumn.setCellRenderer(new DefaultTableCellRenderer() {
- public Component getTableCellRendererComponent(JTable table,
+ @NotNull
+ @Override
+ public Component getTableCellRendererComponent(@NotNull JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
@@ -309,7 +295,7 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
return !DebuggerUtilsEx.externalizableEqual(cloned, myOriginalRenderer);
}
- public void apply() throws ConfigurationException {
+ public void apply() {
if (myRenderer == null) {
return;
}
@@ -342,7 +328,7 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
public void reset() {
final TextWithImports emptyExpressionFragment = new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "");
- ((CardLayout)myMainPanel.getLayout()).show(myMainPanel, myRenderer == null ? EMPTY_PANEL_ID : DATA_PANEL_ID);
+ ((CardLayout)getLayout()).show(this, myRenderer == null ? EMPTY_PANEL_ID : DATA_PANEL_ID);
if (myRenderer == null) {
return;
}
@@ -390,27 +376,11 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
updateContext(className);
}
- public void disposeUIResources() {
- myRenderer = null;
- myOriginalRenderer = null;
- myLabelEditor.dispose();
- myChildrenEditor.dispose();
- myChildrenExpandedEditor.dispose();
- myListChildrenEditor.dispose();
- Disposer.dispose(myClassNameField);
- myLabelEditor = null;
- myChildrenEditor = null;
- myChildrenExpandedEditor = null;
- myListChildrenEditor = null;
- myClassNameField = null;
- myProject = null;
- }
-
private MyTableModel getTableModel() {
return (MyTableModel)myTable.getModel();
}
- private final class MyTableModel extends AbstractTableModel {
+ private static final class MyTableModel extends AbstractTableModel {
private final List<Row> myData = new ArrayList<Row>();
public MyTableModel() {
@@ -423,18 +393,23 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
}
}
+ @Override
public int getColumnCount() {
return 2;
}
+ @Override
public int getRowCount() {
return myData.size();
}
+ @Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
+ @NotNull
+ @Override
public Class getColumnClass(int columnIndex) {
switch (columnIndex) {
case NAME_TABLE_COLUMN:
@@ -446,6 +421,7 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
}
}
+ @Override
public Object getValueAt(int rowIndex, int columnIndex) {
if (rowIndex >= getRowCount()) {
return null;
@@ -461,6 +437,7 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
}
}
+ @Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (rowIndex >= getRowCount()) {
return;
@@ -476,6 +453,8 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
}
}
+ @NotNull
+ @Override
public String getColumnName(int columnIndex) {
switch (columnIndex) {
case NAME_TABLE_COLUMN:
@@ -513,7 +492,7 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
return pairs;
}
- private final class Row {
+ private static final class Row {
public String name;
public TextWithImports value;
diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerLaunchingConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerLaunchingConfigurable.java
index 490f99bb5461..b0748cfd336d 100644
--- a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerLaunchingConfigurable.java
+++ b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerLaunchingConfigurable.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,24 +16,23 @@
package com.intellij.debugger.settings;
import com.intellij.debugger.DebuggerBundle;
-import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.options.OptionsBundle;
+import com.intellij.openapi.options.ConfigurableUi;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.StateRestoringCheckBox;
import com.intellij.ui.components.panels.VerticalBox;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
-public class DebuggerLaunchingConfigurable implements Configurable {
+class DebuggerLaunchingConfigurable implements ConfigurableUi<DebuggerSettings> {
private JRadioButton myRbSocket;
private JRadioButton myRbShmem;
private StateRestoringCheckBox myCbForceClassicVM;
private JCheckBox myCbDisableJIT;
@Override
- public void reset() {
- final DebuggerSettings settings = DebuggerSettings.getInstance();
+ public void reset(@NotNull DebuggerSettings settings) {
if (!SystemInfo.isWindows) {
myRbSocket.setSelected(true);
myRbShmem.setEnabled(false);
@@ -52,8 +51,8 @@ public class DebuggerLaunchingConfigurable implements Configurable {
}
@Override
- public void apply() {
- getSettingsTo(DebuggerSettings.getInstance());
+ public void apply(@NotNull DebuggerSettings settings) {
+ getSettingsTo(settings);
}
private void getSettingsTo(DebuggerSettings settings) {
@@ -68,25 +67,15 @@ public class DebuggerLaunchingConfigurable implements Configurable {
}
@Override
- public boolean isModified() {
- final DebuggerSettings currentSettings = DebuggerSettings.getInstance();
- final DebuggerSettings debuggerSettings = currentSettings.clone();
+ public boolean isModified(@NotNull DebuggerSettings currentSettings) {
+ DebuggerSettings debuggerSettings = currentSettings.clone();
getSettingsTo(debuggerSettings);
return !debuggerSettings.equals(currentSettings);
}
+ @NotNull
@Override
- public String getDisplayName() {
- return OptionsBundle.message("options.java.display.name");
- }
-
- @Override
- public String getHelpTopic() {
- return "reference.idesettings.debugger.launching";
- }
-
- @Override
- public JComponent createComponent() {
+ public JComponent getComponent() {
myCbForceClassicVM = new StateRestoringCheckBox(DebuggerBundle.message("label.debugger.launching.configurable.force.classic.vm"));
myCbDisableJIT = new JCheckBox(DebuggerBundle.message("label.debugger.launching.configurable.disable.jit"));
myRbSocket = new JRadioButton(DebuggerBundle.message("label.debugger.launching.configurable.socket"));
@@ -110,12 +99,6 @@ public class DebuggerLaunchingConfigurable implements Configurable {
JPanel result = new JPanel(new BorderLayout());
result.add(panel, BorderLayout.NORTH);
-
return result;
}
-
-
- @Override
- public void disposeUIResources() {
- }
} \ No newline at end of file
diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.java
index cec458ccbb70..cf7e367f1ce8 100644
--- a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.java
+++ b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.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,10 +17,7 @@ package com.intellij.debugger.settings;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.ui.JavaDebuggerSupport;
-import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.options.OptionsBundle;
-import com.intellij.openapi.options.SearchableConfigurable;
-import com.intellij.openapi.project.Project;
+import com.intellij.openapi.options.ConfigurableUi;
import com.intellij.ui.classFilter.ClassFilterEditor;
import org.jetbrains.annotations.NotNull;
@@ -29,18 +26,16 @@ import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-public class DebuggerSteppingConfigurable implements SearchableConfigurable, Configurable.NoScroll {
+class DebuggerSteppingConfigurable implements ConfigurableUi<DebuggerSettings> {
private JCheckBox myCbStepInfoFiltersEnabled;
private JCheckBox myCbSkipSyntheticMethods;
private JCheckBox myCbSkipConstructors;
private JCheckBox myCbSkipClassLoaders;
private ClassFilterEditor mySteppingFilterEditor;
private JCheckBox myCbSkipSimpleGetters;
- private Project myProject;
@Override
- public void reset() {
- final DebuggerSettings settings = DebuggerSettings.getInstance();
+ public void reset(@NotNull DebuggerSettings settings) {
myCbSkipSimpleGetters.setSelected(settings.SKIP_GETTERS);
myCbSkipSyntheticMethods.setSelected(settings.SKIP_SYNTHETIC_METHODS);
myCbSkipConstructors.setSelected(settings.SKIP_CONSTRUCTORS);
@@ -50,13 +45,11 @@ public class DebuggerSteppingConfigurable implements SearchableConfigurable, Con
mySteppingFilterEditor.setFilters(settings.getSteppingFilters());
mySteppingFilterEditor.setEnabled(settings.TRACING_FILTERS_ENABLED);
-
-
}
@Override
- public void apply() {
- getSettingsTo(DebuggerSettings.getInstance());
+ public void apply(@NotNull DebuggerSettings settings) {
+ getSettingsTo(settings);
}
private void getSettingsTo(DebuggerSettings settings) {
@@ -71,39 +64,16 @@ public class DebuggerSteppingConfigurable implements SearchableConfigurable, Con
}
@Override
- public boolean isModified() {
- final DebuggerSettings currentSettings = DebuggerSettings.getInstance();
- final DebuggerSettings debuggerSettings = currentSettings.clone();
+ public boolean isModified(@NotNull DebuggerSettings currentSettings) {
+ DebuggerSettings debuggerSettings = currentSettings.clone();
getSettingsTo(debuggerSettings);
return !debuggerSettings.equals(currentSettings);
}
@Override
- public String getDisplayName() {
- return OptionsBundle.message("options.java.display.name");
- }
-
- @Override
@NotNull
- public String getHelpTopic() {
- return "reference.idesettings.debugger.stepping";
- }
-
- @Override
- @NotNull
- public String getId() {
- return getHelpTopic();
- }
-
- @Override
- public Runnable enableSearch(String option) {
- return null;
- }
-
- @Override
- public JComponent createComponent() {
+ public JComponent getComponent() {
final JPanel panel = new JPanel(new GridBagLayout());
- myProject = JavaDebuggerSupport.getContextProjectForEditorFieldsInDebuggerConfigurables();
myCbSkipSyntheticMethods = new JCheckBox(DebuggerBundle.message("label.debugger.general.configurable.skip.synthetic.methods"));
myCbSkipConstructors = new JCheckBox(DebuggerBundle.message("label.debugger.general.configurable.skip.constructors"));
myCbSkipClassLoaders = new JCheckBox(DebuggerBundle.message("label.debugger.general.configurable.skip.classLoaders"));
@@ -115,7 +85,7 @@ public class DebuggerSteppingConfigurable implements SearchableConfigurable, Con
panel.add(myCbSkipSimpleGetters, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0),0, 0));
panel.add(myCbStepInfoFiltersEnabled, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(8, 0, 0, 0),0, 0));
- mySteppingFilterEditor = new ClassFilterEditor(myProject, null, "reference.viewBreakpoints.classFilters.newPattern");
+ mySteppingFilterEditor = new ClassFilterEditor(JavaDebuggerSupport.getContextProjectForEditorFieldsInDebuggerConfigurables(), null, "reference.viewBreakpoints.classFilters.newPattern");
panel.add(mySteppingFilterEditor, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 5, 0, 0),0, 0));
myCbStepInfoFiltersEnabled.addActionListener(new ActionListener() {
@@ -126,11 +96,4 @@ public class DebuggerSteppingConfigurable implements SearchableConfigurable, Con
});
return panel;
}
-
- @Override
- public void disposeUIResources() {
- mySteppingFilterEditor = null;
- myProject = null;
- }
-
-}
+} \ No newline at end of file
diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/JavaDebuggerSettings.java b/java/debugger/impl/src/com/intellij/debugger/settings/JavaDebuggerSettings.java
index 7151cb9f650e..e6f271b3981a 100644
--- a/java/debugger/impl/src/com/intellij/debugger/settings/JavaDebuggerSettings.java
+++ b/java/debugger/impl/src/com/intellij/debugger/settings/JavaDebuggerSettings.java
@@ -15,41 +15,78 @@
*/
package com.intellij.debugger.settings;
+import com.intellij.debugger.DebuggerBundle;
import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.OptionsBundle;
+import com.intellij.openapi.options.SimpleConfigurable;
+import com.intellij.openapi.util.Getter;
+import com.intellij.xdebugger.settings.DebuggerSettingsCategory;
import com.intellij.xdebugger.settings.XDebuggerSettings;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static java.util.Collections.singletonList;
+
/**
* We cannot now transform DebuggerSettings to XDebuggerSettings: getState/loadState is not called for EP,
* but we cannot use standard implementation to save our state, due to backward compatibility we must use own state spec.
- *
+ * <p/>
* But we must implement createConfigurable as part of XDebuggerSettings otherwise java general settings will be before xdebugger general setting,
* because JavaDebuggerSettingsPanelProvider has higher priority than XDebuggerSettingsPanelProviderImpl.
*/
-class JavaDebuggerSettings extends XDebuggerSettings<Element> {
+public class JavaDebuggerSettings extends XDebuggerSettings<Element> {
protected JavaDebuggerSettings() {
super("java");
}
- @Nullable
+ @NotNull
@Override
- public Configurable createConfigurable(@NotNull Category category) {
+ public Collection<? extends Configurable> createConfigurables(@NotNull DebuggerSettingsCategory category) {
+ Getter<DebuggerSettings> settingsGetter = new Getter<DebuggerSettings>() {
+ @Override
+ public DebuggerSettings get() {
+ return DebuggerSettings.getInstance();
+ }
+ };
+
switch (category) {
- case ROOT:
- return new DebuggerLaunchingConfigurable();
+ case GENERAL:
+ return singletonList(SimpleConfigurable.create("reference.idesettings.debugger.launching", OptionsBundle.message("options.java.display.name"),
+ DebuggerLaunchingConfigurable.class, settingsGetter));
case DATA_VIEWS:
- return new DebuggerDataViewsConfigurable(null);
+ return createDataViewsConfigurable();
case STEPPING:
- return new DebuggerSteppingConfigurable();
+ return singletonList(SimpleConfigurable.create("reference.idesettings.debugger.stepping", OptionsBundle.message("options.java.display.name"),
+ DebuggerSteppingConfigurable.class, settingsGetter));
+ case HOTSWAP:
+ return singletonList(SimpleConfigurable.create("reference.idesettings.debugger.hotswap", OptionsBundle.message("options.java.display.name"),
+ JavaHotSwapConfigurableUi.class, settingsGetter));
}
- return null;
+ return Collections.emptyList();
+ }
+
+ @SuppressWarnings("SpellCheckingInspection")
+ @NotNull
+ public static List<Configurable> createDataViewsConfigurable() {
+ return Arrays.<Configurable>asList(new DebuggerDataViewsConfigurable(null),
+ SimpleConfigurable.create("reference.idesettings.debugger.typerenderers", DebuggerBundle.message("user.renderers.configurable.display.name"),
+ UserRenderersConfigurable.class, new Getter<NodeRendererSettings>() {
+ @Override
+ public NodeRendererSettings get() {
+ return NodeRendererSettings.getInstance();
+ }
+ }));
}
@Override
- public void generalApplied(@NotNull XDebuggerSettings.Category category) {
- if (category == XDebuggerSettings.Category.DATA_VIEWS) {
+ public void generalApplied(@NotNull DebuggerSettingsCategory category) {
+ if (category == DebuggerSettingsCategory.DATA_VIEWS) {
NodeRendererSettings.getInstance().fireRenderersChanged();
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerHotswapConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/JavaHotSwapConfigurableUi.java
index a70be30556e2..82a33a895fcb 100644
--- a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerHotswapConfigurable.java
+++ b/java/debugger/impl/src/com/intellij/debugger/settings/JavaHotSwapConfigurableUi.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,14 +16,14 @@
package com.intellij.debugger.settings;
import com.intellij.debugger.DebuggerBundle;
-import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.options.ConfigurableUi;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
-public class DebuggerHotswapConfigurable implements SearchableConfigurable {
+class JavaHotSwapConfigurableUi implements ConfigurableUi<DebuggerSettings> {
private JCheckBox myHotswapInBackground;
private JCheckBox myCbCompileBeforeHotswap;
private JCheckBox myCbHangWarningEnabled;
@@ -31,8 +31,8 @@ public class DebuggerHotswapConfigurable implements SearchableConfigurable {
private JRadioButton myRbNever;
private JRadioButton myRbAsk;
- public void reset() {
- final DebuggerSettings settings = DebuggerSettings.getInstance();
+ @Override
+ public void reset(@NotNull DebuggerSettings settings) {
myHotswapInBackground.setSelected(settings.HOTSWAP_IN_BACKGROUND);
myCbCompileBeforeHotswap.setSelected(settings.COMPILE_BEFORE_HOTSWAP);
myCbHangWarningEnabled.setSelected(settings.HOTSWAP_HANG_WARNING_ENABLED);
@@ -48,8 +48,9 @@ public class DebuggerHotswapConfigurable implements SearchableConfigurable {
}
}
- public void apply() {
- getSettingsTo(DebuggerSettings.getInstance());
+ @Override
+ public void apply(@NotNull DebuggerSettings settings) {
+ getSettingsTo(settings);
}
private void getSettingsTo(DebuggerSettings settings) {
@@ -68,31 +69,16 @@ public class DebuggerHotswapConfigurable implements SearchableConfigurable {
}
}
- public boolean isModified() {
- final DebuggerSettings currentSettings = DebuggerSettings.getInstance();
+ @Override
+ public boolean isModified(@NotNull DebuggerSettings currentSettings) {
final DebuggerSettings debuggerSettings = currentSettings.clone();
getSettingsTo(debuggerSettings);
return !debuggerSettings.equals(currentSettings);
}
- public String getDisplayName() {
- return DebuggerBundle.message("debugger.hotswap.configurable.display.name");
- }
-
- public String getHelpTopic() {
- return "reference.idesettings.debugger.hotswap";
- }
-
@NotNull
- public String getId() {
- return getHelpTopic();
- }
-
- public Runnable enableSearch(String option) {
- return null;
- }
-
- public JComponent createComponent() {
+ @Override
+ public JComponent getComponent() {
final JPanel panel = new JPanel(new GridBagLayout());
myCbCompileBeforeHotswap = new JCheckBox(DebuggerBundle.message("label.debugger.hotswap.configurable.compile.before.hotswap"));
@@ -130,9 +116,4 @@ public class DebuggerHotswapConfigurable implements SearchableConfigurable {
return panel;
}
-
-
- public void disposeUIResources() {
- }
-
-}
+} \ No newline at end of file
diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java
index 3ab2028d5813..3a8505c7dfe8 100644
--- a/java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java
+++ b/java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.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,17 +20,12 @@ import com.intellij.debugger.ui.tree.render.CompoundNodeRenderer;
import com.intellij.debugger.ui.tree.render.NodeRenderer;
import com.intellij.ide.util.ElementsChooser;
import com.intellij.openapi.actionSystem.*;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.options.SearchableConfigurable;
-import com.intellij.openapi.project.Project;
+import com.intellij.openapi.options.ConfigurableUi;
import com.intellij.ui.DocumentAdapter;
import com.intellij.util.IconUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.InternalIterator;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
@@ -40,56 +35,25 @@ import java.awt.*;
import java.util.ArrayList;
import java.util.List;
-/**
- * @author Eugene Zhuravlev
- * Date: Feb 19, 2005
- */
-public class UserRenderersConfigurable implements SearchableConfigurable, Configurable.NoScroll {
- private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.settings.UserRenderersConfigurable");
+public final class UserRenderersConfigurable extends JPanel implements ConfigurableUi<NodeRendererSettings> {
private static final Icon ADD_ICON = IconUtil.getAddIcon();
private static final Icon REMOVE_ICON = IconUtil.getRemoveIcon();
private static final Icon COPY_ICON = PlatformIcons.COPY_ICON;
private static final Icon UP_ICON = IconUtil.getMoveUpIcon();
private static final Icon DOWN_ICON = IconUtil.getMoveDownIcon();
- private JPanel myNameFieldPanel;
- private JTextField myNameField;
+ private final JPanel myNameFieldPanel;
+ private final JTextField myNameField;
private ElementsChooser<NodeRenderer> myRendererChooser;
private NodeRenderer myCurrentRenderer = null;
- private final CompoundRendererConfigurable myRendererDataConfigurable;
-
- public UserRenderersConfigurable(@Nullable Project project) {
- myRendererDataConfigurable = new CompoundRendererConfigurable(project);
- }
-
- public String getDisplayName() {
- return DebuggerBundle.message("user.renderers.configurable.display.name");
- }
-
- public String getHelpTopic() {
- return "reference.idesettings.debugger.typerenderers";
- }
-
- @NotNull
- public String getId() {
- return getHelpTopic();
- }
-
- public Runnable enableSearch(String option) {
- return null;
- }
-
- public JComponent createComponent() {
- final JPanel panel = new JPanel(new BorderLayout(4, 0));
+ private final CompoundRendererConfigurable myRendererDataConfigurable = new CompoundRendererConfigurable();
- final JComponent renderersList = createRenderersList();
- final JComponent toolbar = createToolbar();
- final JComponent rendererDataPanel = myRendererDataConfigurable.createComponent();
+ public UserRenderersConfigurable() {
+ super(new BorderLayout(4, 0));
- final JPanel left = new JPanel(new BorderLayout());
-
- left.add(toolbar, BorderLayout.NORTH);
- left.add(renderersList, BorderLayout.CENTER);
+ JPanel left = new JPanel(new BorderLayout());
+ left.add(createToolbar(), BorderLayout.NORTH);
+ left.add(createRenderersList(), BorderLayout.CENTER);
myNameField = new JTextField();
myNameFieldPanel = new JPanel(new BorderLayout());
@@ -98,11 +62,11 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
myNameFieldPanel.setVisible(false);
final JPanel center = new JPanel(new BorderLayout(0, 4));
-
center.add(myNameFieldPanel, BorderLayout.NORTH);
- center.add(rendererDataPanel, BorderLayout.CENTER);
+ center.add(myRendererDataConfigurable, BorderLayout.CENTER);
myNameField.getDocument().addDocumentListener(new DocumentAdapter() {
+ @Override
protected void textChanged(DocumentEvent e) {
if (myCurrentRenderer != null) {
myCurrentRenderer.setName(myNameField.getText());
@@ -111,10 +75,14 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
}
});
- panel.add(left, BorderLayout.WEST);
- panel.add(center, BorderLayout.CENTER);
+ add(left, BorderLayout.WEST);
+ add(center, BorderLayout.CENTER);
+ }
- return panel;
+ @Override
+ @NotNull
+ public JComponent getComponent() {
+ return this;
}
private JComponent createRenderersList() {
@@ -122,12 +90,14 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
myRendererChooser.getEmptyText().setText(DebuggerBundle.message("text.user.renderers.configurable.no.renderers"));
myRendererChooser.addElementsMarkListener(new ElementsChooser.ElementsMarkListener<NodeRenderer>() {
+ @Override
public void elementMarkChanged(final NodeRenderer element, final boolean isMarked) {
element.setEnabled(isMarked);
}
});
myRendererChooser.addListSelectionListener(new ListSelectionListener() {
- public void valueChanged(ListSelectionEvent e) {
+ @Override
+ public void valueChanged(@NotNull ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
updateCurrentRenderer(myRendererChooser.getSelectedElements());
}
@@ -138,7 +108,7 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
private void updateCurrentRenderer(List<NodeRenderer> selectedElements) {
if (selectedElements.size() != 1) {
- // multiselection
+ // multi selection
setCurrentRenderer(null);
}
else {
@@ -150,13 +120,8 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
if (myCurrentRenderer == renderer) {
return;
}
- try {
- if (myRendererDataConfigurable.isModified()) {
- myRendererDataConfigurable.apply();
- }
- }
- catch (ConfigurationException e) {
- LOG.error(e);
+ if (myRendererDataConfigurable.isModified()) {
+ myRendererDataConfigurable.apply();
}
myCurrentRenderer = renderer;
if (renderer != null) {
@@ -181,11 +146,12 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
return toolbar.getComponent();
}
- public void apply() throws ConfigurationException {
+ @Override
+ public void apply(@NotNull NodeRendererSettings settings) {
myRendererDataConfigurable.apply();
- flushTo(NodeRendererSettings.getInstance().getCustomRenderers());
+ flushTo(settings.getCustomRenderers());
- NodeRendererSettings.getInstance().fireRenderersChanged();
+ settings.fireRenderersChanged();
}
private void flushTo(final RendererConfiguration rendererConfiguration) {
@@ -197,11 +163,11 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
rendererConfiguration.setRenderers(renderers);
}
- public boolean isModified() {
+ @Override
+ public boolean isModified(@NotNull NodeRendererSettings settings) {
if (myRendererDataConfigurable.isModified()) {
return true;
}
- final NodeRendererSettings settings = NodeRendererSettings.getInstance();
final RendererConfiguration rendererConfiguration = settings.getCustomRenderers();
if (myRendererChooser.getElementCount() != rendererConfiguration.getRendererCount()) {
return true;
@@ -211,11 +177,13 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
return !uiConfiguration.equals(rendererConfiguration);
}
- public void reset() {
+ @Override
+ public void reset(@NotNull NodeRendererSettings settings) {
myRendererChooser.removeAllElements();
- final RendererConfiguration rendererConfiguration = NodeRendererSettings.getInstance().getCustomRenderers();
+ final RendererConfiguration rendererConfiguration = settings.getCustomRenderers();
final ArrayList<NodeRenderer> elementsToSelect = new ArrayList<NodeRenderer>(1);
rendererConfiguration.iterateRenderers(new InternalIterator<NodeRenderer>() {
+ @Override
public boolean visit(final NodeRenderer renderer) {
final NodeRenderer clonedRenderer = (NodeRenderer)renderer.clone();
myRendererChooser.addElement(clonedRenderer, clonedRenderer.isEnabled());
@@ -230,21 +198,18 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
myRendererDataConfigurable.reset();
}
- public void disposeUIResources() {
- myRendererChooser.removeAllElements();
- myRendererDataConfigurable.disposeUIResources();
- }
-
private class AddAction extends AnAction {
public AddAction() {
super(DebuggerBundle.message("button.add"), DebuggerBundle.message("user.renderers.configurable.button.description.add"), ADD_ICON);
}
+ @Override
public void actionPerformed(AnActionEvent e) {
final NodeRenderer renderer = (NodeRenderer)NodeRendererSettings.getInstance().createRenderer(CompoundNodeRenderer.UNIQUE_ID);
renderer.setEnabled(true);
myRendererChooser.addElement(renderer, renderer.isEnabled());
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
myNameField.requestFocus();
}
@@ -257,16 +222,18 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
super(DebuggerBundle.message("button.remove"), DebuggerBundle.message("user.renderers.configurable.button.description.remove"), REMOVE_ICON);
}
+ @Override
public void actionPerformed(AnActionEvent e) {
for (NodeRenderer selectedElement : myRendererChooser.getSelectedElements()) {
myRendererChooser.removeElement(selectedElement);
}
}
+ @Override
public void update(AnActionEvent e) {
super.update(e);
- final Presentation presentation = e.getPresentation();
- presentation.setEnabled(myRendererChooser.getSelectedElement() != null);
+
+ e.getPresentation().setEnabled(myRendererChooser.getSelectedElement() != null);
}
}
@@ -275,18 +242,18 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
super(DebuggerBundle.message("button.copy"), DebuggerBundle.message("user.renderers.configurable.button.description.copy"), COPY_ICON);
}
+ @Override
public void actionPerformed(AnActionEvent e) {
final NodeRenderer selectedElement = myRendererChooser.getSelectedElement();
if (selectedElement != null) {
- final NodeRenderer cloned = (NodeRenderer)selectedElement.clone();
- myRendererChooser.addElement(cloned, true);
+ myRendererChooser.addElement((NodeRenderer)selectedElement.clone(), true);
}
}
+ @Override
public void update(AnActionEvent e) {
super.update(e);
- final Presentation presentation = e.getPresentation();
- presentation.setEnabled(myRendererChooser.getSelectedElement() != null);
+ e.getPresentation().setEnabled(myRendererChooser.getSelectedElement() != null);
}
}
@@ -300,6 +267,7 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
myMoveUp = up;
}
+ @Override
public void actionPerformed(AnActionEvent e) {
final int selectedRow = myRendererChooser.getSelectedElementRow();
if (selectedRow < 0) {
@@ -315,10 +283,10 @@ public class UserRenderersConfigurable implements SearchableConfigurable, Config
myRendererChooser.moveElement(myRendererChooser.getElementAt(selectedRow), newRow);
}
+ @Override
public void update(AnActionEvent e) {
super.update(e);
- final Presentation presentation = e.getPresentation();
- presentation.setEnabled(myRendererChooser.getSelectedElement() != null);
+ e.getPresentation().setEnabled(myRendererChooser.getSelectedElement() != null);
}
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerPanelsManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerPanelsManager.java
index 3809431c21f8..13336358620b 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerPanelsManager.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerPanelsManager.java
@@ -214,7 +214,7 @@ public class DebuggerPanelsManager implements ProjectComponent {
public void toFront(DebuggerSession session) {
DebuggerSessionTab sessionTab = getSessionTab(session);
if (sessionTab != null) {
- sessionTab.toFront();
+ sessionTab.toFront(true);
}
}
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 27f63e032314..20d95f8fff3d 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java
@@ -18,9 +18,6 @@ package com.intellij.debugger.ui;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.actions.*;
import com.intellij.debugger.impl.DebuggerContextImpl;
-import com.intellij.debugger.settings.DebuggerHotswapConfigurable;
-import com.intellij.debugger.settings.NodeRendererSettings;
-import com.intellij.debugger.settings.UserRenderersConfigurable;
import com.intellij.debugger.ui.breakpoints.Breakpoint;
import com.intellij.ide.DataManager;
import com.intellij.openapi.Disposable;
@@ -28,7 +25,6 @@ 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.options.Configurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.xdebugger.AbstractDebuggerSession;
@@ -42,13 +38,11 @@ import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointItem;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider;
import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
-import com.intellij.xdebugger.impl.settings.DebuggerSettingsPanelProvider;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
-import java.util.ArrayList;
import java.util.Collection;
/**
@@ -68,7 +62,6 @@ public class JavaDebuggerSupport extends DebuggerSupport {
private final ShowExecutionPointActionHandler myShowExecutionPointActionHandler = new ShowExecutionPointActionHandler();
//private final EvaluateActionHandler myEvaluateActionHandler = new EvaluateActionHandler();
private final QuickEvaluateActionHandler myQuickEvaluateHandler = new QuickEvaluateActionHandler();
- private final JavaDebuggerSettingsPanelProvider myDebuggerSettingsPanelProvider = new JavaDebuggerSettingsPanelProvider();
private final DebuggerActionHandler mySmartStepIntoHandler = new JvmSmartStepIntoActionHandler();
private final DebuggerActionHandler myAddToWatchedActionHandler = new AddToWatchActionHandler();
private final JavaMarkObjectActionHandler myMarkObjectActionHandler = new JavaMarkObjectActionHandler();
@@ -118,13 +111,13 @@ public class JavaDebuggerSupport extends DebuggerSupport {
@Override
@NotNull
public DebuggerActionHandler getRunToCursorHandler() {
- return myRunToCursorActionHandler;
+ return DISABLED;
}
@Override
@NotNull
public DebuggerActionHandler getForceRunToCursorHandler() {
- return myForceRunToCursorActionHandler;
+ return DISABLED;
}
@Override
@@ -216,12 +209,6 @@ public class JavaDebuggerSupport extends DebuggerSupport {
return X_EDIT;
}
- @Override
- @NotNull
- public DebuggerSettingsPanelProvider getSettingsPanelProvider() {
- return myDebuggerSettingsPanelProvider;
- }
-
private static class JavaBreakpointPanelProvider extends BreakpointPanelProvider<Breakpoint> {
//private final List<MyBreakpointManagerListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
@@ -335,27 +322,6 @@ public class JavaDebuggerSupport extends DebuggerSupport {
//}
}
- final static class JavaDebuggerSettingsPanelProvider extends DebuggerSettingsPanelProvider {
- @Override
- public int getPriority() {
- return 1;
- }
-
- @NotNull
- @Override
- public Collection<? extends Configurable> getConfigurables() {
- final ArrayList<Configurable> configurables = new ArrayList<Configurable>();
- configurables.add(new UserRenderersConfigurable(null));
- configurables.add(new DebuggerHotswapConfigurable());
- return configurables;
- }
-
- @Override
- public void apply() {
- NodeRendererSettings.getInstance().fireRenderersChanged();
- }
- }
-
public static Project getContextProjectForEditorFieldsInDebuggerConfigurables() {
//todo[nik] improve
Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
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 f06574569db8..98c772d75044 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java
@@ -63,6 +63,6 @@ public class XBreakpointGroupingByPackageRule<B> extends XBreakpointGroupingRule
@Nullable
@Override
public Icon getIcon() {
- return AllIcons.Nodes.Package;
+ return AllIcons.Actions.GroupByPackage;
}
}
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 ebbef2c2ec44..414960b1980a 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
@@ -51,7 +51,7 @@ public class AnyExceptionBreakpoint extends ExceptionBreakpoint {
public void createRequest(DebugProcessImpl debugProcess) {
DebuggerManagerThreadImpl.assertIsManagerThread();
- if (!isEnabled() || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) {
+ if (!shouldCreateRequest(debugProcess)) {
return;
}
super.processClassPrepare(debugProcess, null);
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 6879407b3c9a..328dc5f2cd77 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
@@ -33,6 +33,7 @@ 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.Computable;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizerUtil;
import com.intellij.openapi.util.Key;
@@ -46,6 +47,7 @@ import com.intellij.xdebugger.XExpression;
import com.intellij.xdebugger.breakpoints.SuspendPolicy;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
+import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.XDebuggerHistoryManager;
import com.intellij.xdebugger.impl.XDebuggerUtilImpl;
import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase;
@@ -95,7 +97,20 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
* Request for creating all needed JPDA requests in the specified VM
* @param debuggerProcess the requesting process
*/
- public abstract void createRequest(DebugProcessImpl debuggerProcess);
+ public abstract void createRequest(DebugProcessImpl debugProcess);
+
+ protected boolean shouldCreateRequest(final DebugProcessImpl debugProcess) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ JavaDebugProcess process = debugProcess.getXdebugProcess();
+ return process != null
+ && debugProcess.isAttached()
+ && ((XDebugSessionImpl)process.getSession()).isBreakpointActive(myXBreakpoint)
+ && debugProcess.getRequestsManager().findRequests(Breakpoint.this).isEmpty();
+ }
+ });
+ }
/**
* Request for creating all needed JPDA requests in the specified VM
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 d6cbf1487ab9..cc373743736d 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
@@ -17,10 +17,7 @@ package com.intellij.debugger.ui.breakpoints;
import com.intellij.CommonBundle;
import com.intellij.debugger.*;
-import com.intellij.debugger.engine.DebugProcess;
-import com.intellij.debugger.engine.DebugProcessImpl;
-import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
-import com.intellij.debugger.engine.JVMNameUtil;
+import com.intellij.debugger.engine.*;
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
import com.intellij.debugger.engine.requests.RequestManagerImpl;
import com.intellij.debugger.impl.DebuggerContextImpl;
@@ -300,10 +297,7 @@ public abstract class BreakpointWithHighlighter<P extends JavaBreakpointProperti
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 (!isEnabled() ||
- !debugProcess.isAttached() ||
- isMuted(debugProcess) ||
- !debugProcess.getRequestsManager().findRequests(this).isEmpty()) {
+ if (!shouldCreateRequest(debugProcess)) {
return;
}
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 88ddf4882733..e4f404e909c7 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
@@ -118,7 +118,7 @@ public class ExceptionBreakpoint extends Breakpoint<JavaExceptionBreakpointPrope
public void createRequest(final DebugProcessImpl debugProcess) {
DebuggerManagerThreadImpl.assertIsManagerThread();
- if (!isEnabled() || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) {
+ if (!shouldCreateRequest(debugProcess)) {
return;
}
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
index a537db14b2e8..4e1d3e2adb3f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java
@@ -63,7 +63,7 @@ public abstract class JavaBreakpointTypeBase<T extends JavaBreakpointProperties>
Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint(breakpoint);
if (javaBreakpoint != null) {
PsiClass aClass = javaBreakpoint.getPsiClass();
- if (aClass != null && aClass.getContainingFile() != null) {
+ if (aClass != null && aClass.getContainingFile() != null && aClass.getTextOffset() >= 0) {
return XDebuggerUtil.getInstance().createPositionByOffset(aClass.getContainingFile().getVirtualFile(), aClass.getTextOffset());
}
}
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 5b5233a92157..4d43a2b0d557 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
@@ -123,4 +123,9 @@ public class RunToCursorBreakpoint extends LineBreakpoint {
return new RunToCursorBreakpoint(project, pos, restoreBreakpoints);
}
+
+ @Override
+ protected boolean shouldCreateRequest(DebugProcessImpl debugProcess) {
+ return debugProcess.isAttached() && debugProcess.getRequestsManager().findRequests(this).isEmpty();
+ }
}
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 c106f65cab81..e8b947c0e865 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
@@ -129,7 +129,7 @@ public class WildcardMethodBreakpoint extends Breakpoint<JavaMethodBreakpointPro
public void createRequest(DebugProcessImpl debugProcess) {
DebuggerManagerThreadImpl.assertIsManagerThread();
- if (!isEnabled() || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) {
+ if (!shouldCreateRequest(debugProcess)) {
return;
}
try {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
index abda6968def4..f4da39f318a7 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
@@ -484,7 +484,7 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
}
public boolean canSetValue() {
- return !myIsSynthetic && isLvalue();
+ return myValueReady && !myIsSynthetic && isLvalue();
}
public String getValueLabel() {
@@ -534,4 +534,10 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
}
}
+ public boolean canMark() {
+ if (!myValueReady) {
+ return false;
+ }
+ return getValue() instanceof ObjectReference;
+ }
}
diff --git a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java
index 04af179638cd..27958a922d2c 100644
--- a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java
+++ b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java
@@ -85,7 +85,7 @@ public class ApplicationConfigurable extends SettingsEditor<ApplicationConfigura
public void resetEditorFrom(final ApplicationConfiguration configuration) {
myCommonProgramParameters.reset(configuration);
myModuleSelector.reset(configuration);
- getMainClassField().setText(configuration.MAIN_CLASS_NAME.replaceAll("\\$", "\\."));
+ getMainClassField().setText(configuration.MAIN_CLASS_NAME != null ? configuration.MAIN_CLASS_NAME.replaceAll("\\$", "\\.") : "");
myAlternativeJREPanel.init(configuration.ALTERNATIVE_JRE_PATH, configuration.ALTERNATIVE_JRE_PATH_ENABLED);
updateShowSwingInspector(configuration);
diff --git a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java
index 2370ad3bda71..578d5fbba6ea 100644
--- a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java
+++ b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java
@@ -21,6 +21,7 @@ import com.intellij.execution.configuration.EnvironmentVariablesComponent;
import com.intellij.execution.configurations.*;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.junit.RefactoringListeners;
+import com.intellij.execution.process.KillableColoredProcessHandler;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.util.JavaParametersUtil;
@@ -33,6 +34,7 @@ import com.intellij.openapi.options.SettingsEditorGroup;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
@@ -285,12 +287,17 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration<JavaRunCo
@NotNull
@Override
protected OSProcessHandler startProcess() throws ExecutionException {
- final OSProcessHandler handler = super.startProcess();
+ OSProcessHandler handler = SystemInfo.isWindows ? super.startProcess() : KillableColoredProcessHandler.create(createCommandLine());
RunnerSettings runnerSettings = getRunnerSettings();
JavaRunConfigurationExtensionManager.getInstance().attachExtensionsToProcess(myConfiguration, handler, runnerSettings);
return handler;
}
+ @Override
+ protected boolean ansiColoringEnabled() {
+ return true;
+ }
+
protected ApplicationConfiguration getConfiguration() {
return myConfiguration;
}
diff --git a/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java b/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java
index d472761b017e..3190e19dcee4 100644
--- a/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java
+++ b/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java
@@ -224,9 +224,10 @@ public class DefaultJavaProgramRunner extends JavaPatchableProgramRunner {
threadStates = ThreadDumpParser.parse(stdout);
if (threadStates == null || threadStates.isEmpty()) {
try {
+ //noinspection BusyWait
Thread.sleep(50);
}
- catch (InterruptedException e1) {
+ catch (InterruptedException ignored) {
//
}
threadStates = null;
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java b/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java
index fbe8636ee360..7627d9396fc5 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java
@@ -46,6 +46,7 @@ public class NewProjectWizard extends AbstractProjectWizard {
protected void init(@NotNull ModulesProvider modulesProvider) {
myWizardContext.setNewWizard(true);
+ myWizardContext.setModulesProvider(modulesProvider);
ProjectTypeStep projectTypeStep = new ProjectTypeStep(myWizardContext, this, modulesProvider);
Disposer.register(getDisposable(), projectTypeStep);
mySequence.addCommonStep(projectTypeStep);
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
index 2ed47fd7cb13..8fca04c7aa69 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
@@ -126,6 +126,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D
private final Map<String, ModuleWizardStep> myCustomSteps = new HashMap<String, ModuleWizardStep>();
private final MultiMap<TemplatesGroup,ProjectTemplate> myTemplatesMap;
private String myCurrentCard;
+ private TemplatesGroup myLastSelectedGroup;
public ProjectTypeStep(WizardContext context, NewProjectWizard wizard, ModulesProvider modulesProvider) {
myContext = context;
@@ -369,7 +370,8 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D
// new TemplatesGroup selected
public void projectTypeChanged() {
TemplatesGroup group = getSelectedGroup();
- if (group == null) return;
+ if (group == null || group == myLastSelectedGroup) return;
+ myLastSelectedGroup = group;
PropertiesComponent.getInstance().setValue(PROJECT_WIZARD_GROUP, group.getId() );
ModuleBuilder groupModuleBuilder = group.getModuleBuilder();
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
index 036675179e6f..6c281b0def27 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
@@ -107,6 +107,8 @@ public abstract class FrameworkSupportModelBase extends UserDataHolderBase imple
final FrameworkSupportNode node = mySettingsMap.get(providerId);
if (node != null && enable != node.isChecked()) {
node.setChecked(enable);
+ // ensure configurable to be created and registered to disposer
+ node.getConfigurable();
}
}
diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.java
index d76fa7437167..da18f37c2290 100644
--- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.java
+++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/NamePathComponent.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,12 +19,12 @@ import com.intellij.ide.IdeBundle;
import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.ide.util.BrowseFilesListener;
import com.intellij.openapi.application.ApplicationInfo;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.FieldPanel;
@@ -138,52 +138,40 @@ public class NamePathComponent extends JPanel{
return component;
}
- private String getProjectFilePath(boolean isDefault) {
- if (isDefault) {
- return getPath() + "/" + getNameValue() + ProjectFileType.DOT_DEFAULT_EXTENSION;
- }
- else {
- return getPath() + "/" + Project.DIRECTORY_STORE_FOLDER;
- }
- }
-
- public boolean validateNameAndPath(WizardContext context, boolean defaultFormat) throws
- ConfigurationException {
- final String name = getNameValue();
- if (name.length() == 0) {
- final ApplicationInfo info = ApplicationManager.getApplication().getComponent(ApplicationInfo.class);
- throw new ConfigurationException(
- IdeBundle.message("prompt.new.project.file.name", info.getVersionName(), context.getPresentationName()));
+ public boolean validateNameAndPath(WizardContext context, boolean defaultFormat) throws ConfigurationException {
+ String name = getNameValue();
+ if (StringUtil.isEmptyOrSpaces(name)) {
+ ApplicationInfo info = ApplicationInfo.getInstance();
+ throw new ConfigurationException(IdeBundle.message("prompt.new.project.file.name", info.getVersionName(), context.getPresentationName()));
}
- final String projectFileDirectory = getPath();
- if (projectFileDirectory.length() == 0) {
+ String projectDirectory = getPath();
+ if (StringUtil.isEmptyOrSpaces(projectDirectory)) {
throw new ConfigurationException(IdeBundle.message("prompt.enter.project.file.location", context.getPresentationName()));
}
- if (myShouldBeAbsolute && !new File(projectFileDirectory).isAbsolute()) {
+ if (myShouldBeAbsolute && !new File(projectDirectory).isAbsolute()) {
throw new ConfigurationException(StringUtil.capitalize(IdeBundle.message("file.location.should.be.absolute", context.getPresentationName())));
}
- final boolean shouldPromptCreation = isPathChangedByUser();
- if (!ProjectWizardUtil
- .createDirectoryIfNotExists(IdeBundle.message("directory.project.file.directory", context.getPresentationName()),
- projectFileDirectory, shouldPromptCreation)) {
+
+ boolean shouldPromptCreation = isPathChangedByUser();
+ String message = IdeBundle.message("directory.project.file.directory", context.getPresentationName());
+ if (!ProjectWizardUtil.createDirectoryIfNotExists(message, projectDirectory, shouldPromptCreation)) {
return false;
}
- final File file = new File(projectFileDirectory);
+ File file = new File(projectDirectory);
if (file.exists() && !file.canWrite()) {
- throw new ConfigurationException(String.format("Directory '%s' is not writable!\nPlease choose another project location.", projectFileDirectory));
+ throw new ConfigurationException(String.format("Directory '%s' is not writable!\nPlease choose another project location.", projectDirectory));
}
boolean shouldContinue = true;
- final File projectFile = new File(getProjectFilePath(defaultFormat));
+ String fileName = defaultFormat ? name + ProjectFileType.DOT_DEFAULT_EXTENSION : Project.DIRECTORY_STORE_FOLDER;
+ File projectFile = new File(file, fileName);
if (projectFile.exists()) {
- int answer = Messages.showYesNoDialog(
- IdeBundle.message("prompt.overwrite.project.file", projectFile.getAbsolutePath(), context.getPresentationName()),
- IdeBundle.message("title.file.already.exists"), Messages.getQuestionIcon());
+ message = IdeBundle.message("prompt.overwrite.project.file", projectFile.getAbsolutePath(), context.getPresentationName());
+ int answer = Messages.showYesNoDialog(message, IdeBundle.message("title.file.already.exists"), Messages.getQuestionIcon());
shouldContinue = (answer == Messages.YES);
}
-
return shouldContinue;
}
@@ -204,14 +192,15 @@ public class NamePathComponent extends JPanel{
}
public String getPath() {
- return myTfPath.getText().trim().replace(File.separatorChar, '/');
+ String text = myTfPath.getText().trim();
+ return FileUtil.expandUserHome(FileUtil.toSystemIndependentName(text));
}
public void setPath(String path) {
final boolean isPathChangedByUser = myIsPathChangedByUser;
setPathNameSyncEnabled(false);
try {
- myTfPath.setText(path);
+ myTfPath.setText(FileUtil.getLocationRelativeToUserHome(FileUtil.toSystemDependentName(path)));
}
finally {
myIsPathChangedByUser = isPathChangedByUser;
diff --git a/java/idea-ui/src/com/intellij/openapi/projectRoots/ui/SdkEditor.java b/java/idea-ui/src/com/intellij/openapi/projectRoots/ui/SdkEditor.java
index 68e174159e1a..0c41048c0db8 100644
--- a/java/idea-ui/src/com/intellij/openapi/projectRoots/ui/SdkEditor.java
+++ b/java/idea-ui/src/com/intellij/openapi/projectRoots/ui/SdkEditor.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.
@@ -32,6 +32,7 @@ import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.TabbedPaneWrapper;
import com.intellij.ui.navigation.History;
@@ -151,11 +152,13 @@ public class SdkEditor implements Configurable, Place.Navigator {
myHomeComponent.getTextField().setEditable(false);
myHomeFieldLabel = new JLabel(getHomeFieldLabelValue());
- myMainPanel.add(myHomeFieldLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 0, 2, 2), 0, 0));
- myMainPanel.add(myHomeComponent, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 0), 0, 0));
+ final int leftInset = Registry.is("ide.new.project.settings") ? 10 : 0;
+ final int rightInset = Registry.is("ide.new.project.settings") ? 10 : 0;
+ myMainPanel.add(myHomeFieldLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, leftInset, 2, 2), 0, 0));
+ myMainPanel.add(myHomeComponent, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, rightInset), 0, 0));
myAdditionalDataPanel = new JPanel(new BorderLayout());
- myMainPanel.add(myAdditionalDataPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2, 0, 0, 0), 0, 0));
+ myMainPanel.add(myAdditionalDataPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2, leftInset, 0, rightInset), 0, 0));
myMainPanel.add(myTabbedPane.getComponent(), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2, 0, 0, 0), 0, 0));
}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java
index cbfd826d8462..73f9f7f39807 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.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.
@@ -26,6 +26,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -140,6 +141,7 @@ public class JavaContentEntriesEditor extends CommonContentEntriesEditor {
@Override
protected JPanel createBottomControl(Module module) {
+ if (Registry.is("ide.new.project.settings")) return null;
final JPanel innerPanel = new JPanel(new GridBagLayout());
innerPanel.setBorder(BorderFactory.createEmptyBorder(6, 0, 0, 6));
return innerPanel;
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.form b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.form
index 292c1f6c81c6..576d5146ff89 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.form
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.form
@@ -1,12 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.openapi.roots.ui.configuration.ProjectConfigurable">
<grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="10">
- <margin top="14" left="4" bottom="4" right="4"/>
+ <margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="20" y="20" width="907" height="282"/>
+ <xy x="20" y="20" width="907" height="288"/>
</constraints>
<properties/>
- <border type="none"/>
+ <border type="none">
+ <size top="14" left="10" bottom="14" right="10"/>
+ </border>
<children>
<vspacer id="2fb9d">
<constraints>
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectConfigurable.java
index 9c46d56ce21e..2bc8499e6c01 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectConfigurable.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 com.intellij.openapi.ui.DetailsComponent;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.pom.java.LanguageLevel;
@@ -49,6 +50,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.io.IOException;
@@ -108,7 +110,7 @@ public class ProjectConfigurable extends ProjectStructureElementConfigurable<Pro
@Override
public JComponent createOptionsPanel() {
- myDetailsComponent = new DetailsComponent();
+ myDetailsComponent = new DetailsComponent(!Registry.is("ide.new.project.settings"), !Registry.is("ide.new.project.settings"));
myDetailsComponent.setContent(myPanel);
myDetailsComponent.setText(getBannerSlogan());
@@ -152,7 +154,7 @@ public class ProjectConfigurable extends ProjectStructureElementConfigurable<Pro
myPanel.add(myWholePanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(4, 0, 0, 0), 0, 0));
-
+ myPanel.setBorder(new EmptyBorder(0, 10, 0, 10));
myProjectCompilerOutput.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent e) {
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java
index d78731b0a3c8..f24153739031 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.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.
@@ -161,6 +161,9 @@ public class ProjectJdksConfigurable extends MasterDetailsComponent {
@Override
@Nullable
protected ArrayList<AnAction> createActions(final boolean fromPopup) {
+ if (myProjectJdksModel == null) {
+ return null;
+ }
final ArrayList<AnAction> actions = new ArrayList<AnAction>();
DefaultActionGroup group = new DefaultActionGroup(ProjectBundle.message("add.new.jdk.text"), true);
group.getTemplatePresentation().setIcon(IconUtil.getAddIcon());
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
index bf083f92c66c..a5867d66d176 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
@@ -44,6 +44,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.ui.JBSplitter;
+import com.intellij.ui.OnePixelSplitter;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.ui.navigation.BackAction;
import com.intellij.ui.navigation.ForwardAction;
@@ -174,12 +175,9 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se
public JComponent createComponent() {
myComponent = new MyPanel();
- mySplitter = new JBSplitter(false, .15f);
+ mySplitter = Registry.is("ide.new.project.settings") ? new OnePixelSplitter(false, .15f) : new JBSplitter(false, .15f);
mySplitter.setSplitterProportionKey("ProjectStructure.TopLevelElements");
mySplitter.setHonorComponentsMinimumSize(true);
- if (Registry.is("ide.new.project.settings")) {
- mySplitter.setOnePixelMode();
- }
initSidePanel();
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java
index 290f35e561b5..355888b02a42 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java
@@ -20,7 +20,10 @@ import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.openapi.ui.popup.ListItemDescriptor;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.ui.*;
+import com.intellij.ui.Gray;
+import com.intellij.ui.JBColor;
+import com.intellij.ui.ScrollPaneFactory;
+import com.intellij.ui.SeparatorWithText;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.navigation.History;
@@ -172,16 +175,14 @@ public class SidePanel extends JPanel {
protected JComponent createItemComponent() {
myExtraPanel = new NonOpaquePanel(new BorderLayout());
myCountLabel = new CountLabel();
-
+ final JComponent component = super.createItemComponent();
if (Registry.is("ide.new.project.settings")) {
- myTextLabel = new EngravedLabel();
- myTextLabel.setFont(myTextLabel.getFont().deriveFont(Font.BOLD));
myTextLabel.setForeground(Gray._240);
myTextLabel.setOpaque(true);
- return layoutComponent(myTextLabel);
}
- return super.createItemComponent();
+
+ return component;
}
@Override
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java
index 69b490828f0b..618f085f00bb 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,12 +34,12 @@ import com.intellij.openapi.roots.ui.configuration.artifacts.sourceItems.Library
import com.intellij.openapi.roots.ui.configuration.artifacts.sourceItems.ModuleOutputSourceItem;
import com.intellij.openapi.roots.ui.configuration.artifacts.sourceItems.SourceItemsTree;
import com.intellij.openapi.ui.FixedSizeButton;
-import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
@@ -83,6 +83,7 @@ public class ArtifactEditorImpl implements ArtifactEditorEx {
private JPanel myErrorPanelPlace;
private ThreeStateCheckBox myShowContentCheckBox;
private FixedSizeButton myShowSpecificContentOptionsButton;
+ private JPanel myTopPanel;
private final ActionGroup myShowSpecificContentOptionsGroup;
private final Project myProject;
private final ComplexElementSubstitutionParameters mySubstitutionParameters = new ComplexElementSubstitutionParameters();
@@ -106,6 +107,9 @@ public class ArtifactEditorImpl implements ArtifactEditorEx {
myPropertiesEditors = new ArtifactPropertiesEditors(myContext, myOriginalArtifact, myOriginalArtifact);
Disposer.register(this, mySourceItemsTree);
Disposer.register(this, myLayoutTreeComponent);
+ if (Registry.is("ide.new.project.settings")) {
+ myTopPanel.setBorder(new EmptyBorder(0, 10, 0, 10));
+ }
myBuildOnMakeCheckBox.setSelected(artifact.isBuildOnMake());
final String outputPath = artifact.getOutputPath();
myOutputDirectoryField.addBrowseFolderListener(CompilerBundle.message("dialog.title.output.directory.for.artifact"),
@@ -202,7 +206,7 @@ public class ArtifactEditorImpl implements ArtifactEditorEx {
myErrorPanelPlace.add(myValidationManager.getMainErrorPanel(), BorderLayout.CENTER);
- Splitter splitter = new Splitter(false);
+ final JBSplitter splitter = Registry.is("ide.new.project.settings") ? new OnePixelSplitter(false) : new JBSplitter(false);
final JPanel leftPanel = new JPanel(new BorderLayout());
JPanel treePanel = myLayoutTreeComponent.getTreePanel();
if (UIUtil.isUnderDarcula()) {
@@ -213,7 +217,7 @@ public class ArtifactEditorImpl implements ArtifactEditorEx {
leftPanel.add(treePanel, BorderLayout.CENTER);
if (UIUtil.isUnderDarcula()) {
CompoundBorder border =
- new CompoundBorder(new CustomLineBorder(UIUtil.getBorderColor(), 0, 0, 0, 1), BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ new CompoundBorder(new CustomLineBorder(0, 0, 0, 1), BorderFactory.createEmptyBorder(0, 0, 0, 0));
leftPanel.setBorder(border);
} else {
leftPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 0));
@@ -241,7 +245,7 @@ public class ArtifactEditorImpl implements ArtifactEditorEx {
labelPanel.add(link);
rightTopPanel.add(labelPanel, BorderLayout.CENTER);
rightPanel.add(rightTopPanel, BorderLayout.NORTH);
- JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(mySourceItemsTree, UIUtil.isUnderDarcula());
+ JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(mySourceItemsTree, UIUtil.isUnderDarcula() || Registry.is("ide.new.project.settings"));
JPanel scrollPaneWrap = new JPanel(new BorderLayout());
scrollPaneWrap.add(scrollPane, BorderLayout.CENTER);
if (UIUtil.isUnderDarcula()) {
@@ -257,6 +261,13 @@ public class ArtifactEditorImpl implements ArtifactEditorEx {
rightPanel.setBorder(BorderFactory.createEmptyBorder(3, 0, 3, 3));
}
splitter.setSecondComponent(rightPanel);
+ if (Registry.is("ide.new.project.settings")) {
+ splitter.getDivider().setBackground(UIUtil.getPanelBackground());
+ treePanel.setBorder(new EmptyBorder(0, 0, 0, 0));
+ rightPanel.setBorder(new EmptyBorder(0, 0, 0, 0));
+ scrollPaneWrap.setBorder(new EmptyBorder(0,0,0,0));
+ leftPanel.setBorder(new EmptyBorder(0,0,0,0));
+ }
myShowContentCheckBox.addActionListener(new ActionListener() {
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsEditorImpl.form b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsEditorImpl.form
index d3edac73dcf3..17c98953e52a 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsEditorImpl.form
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsEditorImpl.form
@@ -8,7 +8,7 @@
<properties/>
<border type="none"/>
<children>
- <grid id="6e544" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="6e544" binding="myTopPanel" 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="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java
index 52b601e4d9fe..5deea9c75f74 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java
@@ -286,25 +286,7 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable {
}
private void addArtifact(@NotNull ArtifactType type, @NotNull ArtifactTemplate artifactTemplate) {
- final ArtifactTemplate.NewArtifactConfiguration configuration = artifactTemplate.createArtifact();
- if (configuration == null) {
- return;
- }
-
- final String baseName = configuration.getArtifactName();
- String name = baseName;
- int i = 2;
- while (myPackagingEditorContext.getArtifactModel().findArtifact(name) != null) {
- name = baseName + i;
- i++;
- }
-
- ArtifactType actualType = configuration.getArtifactType();
- if (actualType == null) {
- actualType = type;
- }
- final ModifiableArtifact artifact = myPackagingEditorContext.getOrCreateModifiableArtifactModel().addArtifact(name, actualType, configuration.getRootElement());
- artifactTemplate.setUpArtifact(artifact, configuration);
+ Artifact artifact = ArtifactUtil.addArtifact(myPackagingEditorContext.getOrCreateModifiableArtifactModel(), type, artifactTemplate);
selectNodeInTree(findNodeByObject(myRoot, artifact));
}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTreeComponent.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTreeComponent.java
index ff1fdd393961..d8392ea73e63 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTreeComponent.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTreeComponent.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.
@@ -47,7 +47,6 @@ import com.intellij.ui.treeStructure.SimpleTreeStructure;
import com.intellij.ui.treeStructure.WeightBasedComparator;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -132,7 +131,7 @@ public class LayoutTreeComponent implements DnDTarget, Disposable {
emptyPanel.setPreferredSize(new Dimension(0, 0));
myPropertiesPanelWrapper = new JPanel(new CardLayout());
- myPropertiesPanel.setBorder(new CustomLineBorder(UIUtil.getBorderColor(), 1, 0, 0, 0));
+ myPropertiesPanel.setBorder(new CustomLineBorder(1, 0, 0, 0));
myPropertiesPanelWrapper.add(EMPTY_CARD, emptyPanel);
myPropertiesPanelWrapper.add(PROPERTIES_CARD, myPropertiesPanel);
}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java
index 5d884a6f9bc8..e47e955fff24 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java
@@ -41,6 +41,7 @@ import com.intellij.openapi.ui.ex.MultiLineLabel;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -48,6 +49,7 @@ import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.ui.AnActionButton;
import com.intellij.ui.AnActionButtonRunnable;
import com.intellij.ui.ToolbarDecorator;
+import com.intellij.ui.border.CustomLineBorder;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IconUtil;
@@ -157,7 +159,9 @@ public class LibraryRootsComponent implements Disposable, LibraryEditorComponent
ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(myTree).disableUpDownActions()
.setRemoveActionName(ProjectBundle.message("library.remove.action"))
.disableRemoveAction();
-
+ if (Registry.is("ide.new.project.settings")) {
+ toolbarDecorator.setPanelBorder(new CustomLineBorder(1, 0, 0, 0));
+ }
final List<AttachRootButtonDescriptor> popupItems = new ArrayList<AttachRootButtonDescriptor>();
for (AttachRootButtonDescriptor descriptor : myDescriptor.createAttachButtons()) {
Icon icon = descriptor.getToolbarIcon();
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java
index b88f92474fcf..a3b1db0dcf24 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java
@@ -38,7 +38,6 @@ import com.intellij.openapi.ui.NamedConfigurable;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.ui.TreeSpeedSearch;
@@ -302,7 +301,7 @@ public abstract class BaseStructureConfigurable extends MasterDetailsComponent i
result.addAll(copyActions);
result.add(Separator.getInstance());
- if (fromPopup || !(SystemInfo.isMac && Registry.is("ide.new.project.settings"))) {
+ if (fromPopup || !Registry.is("ide.new.project.settings")) {
result.add(new MyFindUsagesAction(myTree));
}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java
index e5a008d3dcbb..d5248a55e7ad 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.FacetProje
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement;
import com.intellij.openapi.ui.DetailsComponent;
import com.intellij.openapi.ui.NamedConfigurable;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
import com.intellij.util.ui.tree.TreeUtil;
@@ -277,8 +278,10 @@ public class FacetStructureConfigurable extends BaseStructureConfigurable {
actions.add(new MyNavigateAction());
}
actions.add(new MyRemoveAction());
- actions.add(Separator.getInstance());
- addCollapseExpandActions(actions);
+ if (fromPopup || !(Registry.is("ide.new.project.settings"))) {
+ actions.add(Separator.getInstance());
+ addCollapseExpandActions(actions);
+ }
return actions;
}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetsTreeCellRenderer.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetsTreeCellRenderer.java
index d89fe3797478..216ad982bbd3 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetsTreeCellRenderer.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetsTreeCellRenderer.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.
@@ -54,15 +54,7 @@ public class FacetsTreeCellRenderer extends GroupedElementsRenderer.Tree {
if (configurable != null) {
final Icon icon = configurable.getIcon(expanded);
final boolean showSeparator = configurable instanceof FrameworkDetectionConfigurable;
- int width = -1;
- if (showSeparator && tree.isVisible()) {
- final int treeWidth = tree.getVisibleRect().width;
- if (treeWidth > 0) {
- width = treeWidth;
- }
- }
- final JComponent component = configureComponent(node.getDisplayName(), null, icon, icon, selected, showSeparator, null,
- width);
+ final JComponent component = configureComponent(node.getDisplayName(), null, icon, icon, selected, showSeparator, null, -1);
myTextLabel.setOpaque(selected);
return component;
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
index 1c313c1077ee..a2a7e6b5c76f 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
@@ -53,7 +53,6 @@ import com.intellij.openapi.ui.*;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.NullableComputable;
-import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
@@ -149,9 +148,9 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
@NotNull
protected ArrayList<AnAction> createActions(final boolean fromPopup) {
final ArrayList<AnAction> result = super.createActions(fromPopup);
- result.add(Separator.getInstance());
- result.add(new MyGroupAction());
- if (fromPopup || !(SystemInfo.isMac && Registry.is("ide.new.project.settings"))) {
+ if (fromPopup || !Registry.is("ide.new.project.settings")) {
+ result.add(Separator.getInstance());
+ result.add(new MyGroupAction());
addCollapseExpandActions(result);
}
return result;
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 7f8d01382b09..c23ebdd00855 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
@@ -1292,5 +1292,31 @@ public class GenericsHighlightUtil {
}
}
}
+
+ public static HighlightInfo checkInferredIntersections(PsiSubstitutor substitutor, TextRange ref) {
+ for (Map.Entry<PsiTypeParameter, PsiType> typeEntry : substitutor.getSubstitutionMap().entrySet()) {
+ final PsiType type = typeEntry.getValue();
+ if (type instanceof PsiIntersectionType) {
+ final PsiType[] conjuncts = ((PsiIntersectionType)type).getConjuncts();
+ for (int i = 0; i < conjuncts.length; i++) {
+ PsiClass conjunct = PsiUtil.resolveClassInClassTypeOnly(conjuncts[i]);
+ if (conjunct != null && !conjunct.isInterface()) {
+ for (int i1 = i + 1; i1 < conjuncts.length; i1++) {
+ PsiClass oppositeConjunct = PsiUtil.resolveClassInClassTypeOnly(conjuncts[i1]);
+ if (oppositeConjunct != null && !oppositeConjunct.isInterface()) {
+ if (!conjunct.isInheritor(oppositeConjunct, true) && !oppositeConjunct.isInheritor(conjunct, true)) {
+ return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
+ .descriptionAndTooltip("Type parameter " + typeEntry.getKey().getName() + " has incompatible upper bounds: " +
+ conjunct.getName() + " and " + oppositeConjunct.getName())
+ .range(ref).create();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java
index 602e3fea2cc2..a4ea7087af5a 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java
@@ -696,14 +696,17 @@ public class HighlightControlFlowUtil {
return true;
}
- if (ControlFlowUtil.isVariableDefinitelyAssigned(variable, controlFlow)) {
- final Collection<ControlFlowUtil.VariableInfo> initializedTwice = ControlFlowUtil.getInitializedTwice(controlFlow);
- effectivelyFinal = !initializedTwice.contains(new ControlFlowUtil.VariableInfo(variable, null));
- if (effectivelyFinal) {
- effectivelyFinal = notAccessedForWriting(variable, new LocalSearchScope(scope));
+ final List<PsiReferenceExpression> readBeforeWriteLocals = ControlFlowUtil.getReadBeforeWriteLocals(controlFlow);
+ for (PsiReferenceExpression expression : readBeforeWriteLocals) {
+ if (expression.resolve() == variable) {
+ return PsiUtil.isAccessedForReading(expression);
}
- } else {
- effectivelyFinal = false;
+ }
+
+ final Collection<ControlFlowUtil.VariableInfo> initializedTwice = ControlFlowUtil.getInitializedTwice(controlFlow);
+ effectivelyFinal = !initializedTwice.contains(new ControlFlowUtil.VariableInfo(variable, null));
+ if (effectivelyFinal) {
+ effectivelyFinal = notAccessedForWriting(variable, new LocalSearchScope(scope));
}
}
return effectivelyFinal;
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
index b567ce41325a..118c98efc9d2 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
@@ -344,8 +344,12 @@ public class HighlightMethodUtil {
if (resolved instanceof PsiMethod && resolveResult.isValidResult()) {
TextRange fixRange = getFixRange(methodCall);
highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall, fixRange);
- if (highlightInfo == null && !LambdaUtil.isValidQualifier4InterfaceStaticMethodCall((PsiMethod)resolved, methodCall.getMethodExpression(), resolveResult.getCurrentFileResolveScope(), languageLevel)) {
- highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip("Static method may be invoked on containing interface class only").range(fixRange).create();
+ if (highlightInfo == null) {
+ if (!LambdaUtil.isValidQualifier4InterfaceStaticMethodCall((PsiMethod)resolved, methodCall.getMethodExpression(), resolveResult.getCurrentFileResolveScope(), languageLevel)) {
+ highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip("Static method may be invoked on containing interface class only").range(fixRange).create();
+ } else {
+ highlightInfo = GenericsHighlightUtil.checkInferredIntersections(substitutor, fixRange);
+ }
}
}
else {
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 c1f127d3a1df..621ce3fce2af 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java
@@ -141,7 +141,19 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
.inferTypeArguments(method.getTypeParameters(), parameters, expressions,
((MethodCandidateInfo)result).getSiteSubstitutor(), callExpr.getParent(),
DefaultParameterTypeInferencePolicy.INSTANCE);
- return substitutor.substitute(parameters[i].getType());
+ PsiType paramType;
+ if (i < parameters.length) {
+ paramType = parameters[i].getType();
+ }
+ else {
+ paramType = parameters[parameters.length - 1].getType();
+ if (!(paramType instanceof PsiEllipsisType)) {
+ return null;
+ }
+ paramType = ((PsiEllipsisType)paramType).getComponentType();
+ }
+
+ return substitutor.substitute(paramType);
}
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Analysis.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Analysis.java
index 44e493c63f0a..47ef448c7484 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Analysis.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Analysis.java
@@ -208,7 +208,8 @@ class MakeResult<Res> implements PendingAction<Res> {
}
abstract class Analysis<Res> {
- private static final int STEPS_LIMIT = 30000;
+ public static final int STEPS_LIMIT = 30000;
+ public static final int EQUATION_SIZE_LIMIT = 30;
final RichControlFlow richControlFlow;
final Direction direction;
final ControlFlowGraph controlFlow;
@@ -225,7 +226,7 @@ abstract class Analysis<Res> {
Res earlyResult = null;
abstract Res identity();
- abstract Res combineResults(Res delta, List<Res> subResults);
+ abstract Res combineResults(Res delta, List<Res> subResults) throws AnalyzerException;
abstract boolean isEarlyResult(Res res);
abstract Equation<Key, Value> mkEquation(Res result);
abstract void processState(State state) throws AnalyzerException;
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java
index f29dd7f6cf0c..0239a661c4ee 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java
@@ -15,112 +15,68 @@
*/
package com.intellij.codeInspection.bytecodeAnalysis;
-import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.util.io.*;
-import gnu.trove.TIntHashSet;
-import gnu.trove.TIntObjectHashMap;
-import gnu.trove.TIntObjectIterator;
+import gnu.trove.TLongArrayList;
+import gnu.trove.TLongHashSet;
+import gnu.trove.TLongObjectHashMap;
+import gnu.trove.TLongObjectIterator;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Type;
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.File;
import java.io.IOException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
import static com.intellij.codeInspection.bytecodeAnalysis.ProjectBytecodeAnalysis.LOG;
/**
* @author lambdamix
*/
-public class BytecodeAnalysisConverter implements ApplicationComponent {
+public abstract class BytecodeAnalysisConverter implements ApplicationComponent {
- private static final String VERSION = "BytecodeAnalysisConverter.Enumerators";
+ public static final int SHIFT = 4096;
public static BytecodeAnalysisConverter getInstance() {
return ApplicationManager.getApplication().getComponent(BytecodeAnalysisConverter.class);
}
- private PersistentStringEnumerator myNamesEnumerator;
- private PersistentEnumeratorDelegate<int[]> myCompoundKeyEnumerator;
- private int version;
-
- @Override
- public void initComponent() {
- version = PropertiesComponent.getInstance().getOrInitInt(VERSION, 0);
- final File keysDir = new File(PathManager.getIndexRoot(), "bytecodekeys");
- final File namesFile = new File(keysDir, "names");
- final File compoundKeysFile = new File(keysDir, "compound");
-
- try {
- IOUtil.openCleanOrResetBroken(new ThrowableComputable<Void, IOException>() {
- @Override
- public Void compute() throws IOException {
- myNamesEnumerator = new PersistentStringEnumerator(namesFile, true);
- myCompoundKeyEnumerator = new IntArrayPersistentEnumerator(compoundKeysFile, new IntArrayKeyDescriptor());
- return null;
- }
- }, new Runnable() {
- @Override
- public void run() {
- LOG.info("Error during initialization of enumerators in bytecode analysis. Re-initializing.");
- IOUtil.deleteAllFilesStartingWith(keysDir);
- version ++;
- }
- });
- }
- catch (IOException e) {
- LOG.error("Re-initialization of enumerators in bytecode analysis failed.", e);
- }
- // TODO: is it enough for rebuilding indices?
- PropertiesComponent.getInstance().setValue(VERSION, String.valueOf(version));
- }
-
- @Override
- public void disposeComponent() {
- try {
- myNamesEnumerator.close();
- myCompoundKeyEnumerator.close();
- }
- catch (IOException e) {
- LOG.debug(e);
- }
- }
-
@NotNull
@Override
public String getComponentName() {
return "BytecodeAnalysisConverter";
}
- IntIdEquation convert(Equation<Key, Value> equation) throws IOException {
+ public abstract int getVersion();
+
+ protected abstract int enumerateString(@NotNull String s) throws IOException;
+
+ protected abstract int enumerateCompoundKey(@NotNull int[] key) throws IOException;
+
+ IdEquation convert(Equation<Key, Value> equation) throws IOException {
ProgressManager.checkCanceled();
Result<Key, Value> rhs = equation.rhs;
- IntIdResult result;
+ IdResult result;
if (rhs instanceof Final) {
- result = new IntIdFinal(((Final<Key, Value>)rhs).value);
+ result = new IdFinal(((Final<Key, Value>)rhs).value);
} else {
Pending<Key, Value> pending = (Pending<Key, Value>)rhs;
Set<Product<Key, Value>> sumOrigin = pending.sum;
IntIdComponent[] components = new IntIdComponent[sumOrigin.size()];
int componentI = 0;
for (Product<Key, Value> prod : sumOrigin) {
- int[] intProd = new int[prod.ids.size()];
+ long[] intProd = new long[prod.ids.size()];
int idI = 0;
for (Key id : prod.ids) {
- int rawId = mkAsmKey(id);
+ long rawId = mkAsmKey(id);
if (rawId <= 0) {
LOG.error("raw key should be positive. rawId = " + rawId);
}
@@ -131,24 +87,51 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
components[componentI] = intIdComponent;
componentI++;
}
- result = new IntIdPending(components);
+ result = new IdPending(components);
}
- int rawKey = mkAsmKey(equation.id);
+ long rawKey = mkAsmKey(equation.id);
if (rawKey <= 0) {
LOG.error("raw key should be positive. rawKey = " + rawKey);
}
- int key = equation.id.stable ? rawKey : -rawKey;
- return new IntIdEquation(key, result);
+ long key = equation.id.stable ? rawKey : -rawKey;
+ return new IdEquation(key, result);
}
- public int mkAsmKey(@NotNull Key key) throws IOException {
- return myCompoundKeyEnumerator.enumerate(new int[]{mkDirectionKey(key.direction), mkAsmSignatureKey(key.method)});
+ public long mkAsmKey(@NotNull Key key) throws IOException {
+ long baseKey = mkAsmSignatureKey(key.method);
+ long directionKey = mkDirectionKey(key.direction);
+ return baseKey * SHIFT + directionKey;
}
- private int mkDirectionKey(Direction dir) throws IOException {
- return myCompoundKeyEnumerator.enumerate(new int[]{dir.directionId(), dir.paramId(), dir.valueId()});
+ private static int mkDirectionKey(Direction dir) throws IOException {
+ if (dir instanceof Out) {
+ return 0;
+ } else if (dir instanceof In) {
+ In in = (In)dir;
+ return 8 * in.paramId() + 1;
+ } else {
+ InOut inOut = (InOut)dir;
+ return 8 * inOut.paramId() + 2 + inOut.valueId();
+ }
+ }
+
+ @NotNull
+ private static Direction extractDirection(int directionKey) {
+ if (directionKey == 0) {
+ return new Out();
+ }
+ else {
+ int paramId = directionKey / 8;
+ int subDirection = directionKey % 8;
+ if (subDirection == 1) {
+ return new In(paramId);
+ }
+ else {
+ return new InOut(paramId, Value.values()[subDirection - 2]);
+ }
+ }
}
// class + short signature
@@ -156,33 +139,19 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
int[] sigKey = new int[2];
sigKey[0] = mkAsmTypeKey(Type.getObjectType(method.internalClassName));
sigKey[1] = mkAsmShortSignatureKey(method);
- return myCompoundKeyEnumerator.enumerate(sigKey);
+ return enumerateCompoundKey(sigKey);
}
private int mkAsmShortSignatureKey(@NotNull Method method) throws IOException {
Type[] argTypes = Type.getArgumentTypes(method.methodDesc);
int arity = argTypes.length;
- int[] sigKey = new int[3 + arity];
+ int[] sigKey = new int[2 + arity];
sigKey[0] = mkAsmTypeKey(Type.getReturnType(method.methodDesc));
- sigKey[1] = myNamesEnumerator.enumerate(method.methodName);
- sigKey[2] = argTypes.length;
+ sigKey[1] = enumerateString(method.methodName);
for (int i = 0; i < argTypes.length; i++) {
- sigKey[3 + i] = mkAsmTypeKey(argTypes[i]);
+ sigKey[2 + i] = mkAsmTypeKey(argTypes[i]);
}
- return myCompoundKeyEnumerator.enumerate(sigKey);
- }
-
- @Nullable
- private static Direction extractDirection(int[] directionKey) {
- switch (directionKey[0]) {
- case Direction.OUT_DIRECTION:
- return new Out();
- case Direction.IN_DIRECTION:
- return new In(directionKey[1]);
- case Direction.INOUT_DIRECTION:
- return new InOut(directionKey[1], Value.values()[directionKey[2]]);
- }
- return null;
+ return enumerateCompoundKey(sigKey);
}
private int mkAsmTypeKey(Type type) throws IOException {
@@ -197,22 +166,22 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
packageName = "";
simpleName = className;
}
- int[] classKey = new int[]{myNamesEnumerator.enumerate(packageName), myNamesEnumerator.enumerate(simpleName)};
- return myCompoundKeyEnumerator.enumerate(classKey);
+ int[] classKey = new int[]{enumerateString(packageName), enumerateString(simpleName)};
+ return enumerateCompoundKey(classKey);
}
- public int mkPsiKey(@NotNull PsiMethod psiMethod, Direction direction) throws IOException {
+ public long mkPsiKey(@NotNull PsiMethod psiMethod, Direction direction) throws IOException {
final PsiClass psiClass = PsiTreeUtil.getParentOfType(psiMethod, PsiClass.class, false);
if (psiClass == null) {
LOG.debug("PsiClass was null for " + psiMethod.getName());
return -1;
}
- int sigKey = mkPsiSignatureKey(psiMethod);
+ long sigKey = mkPsiSignatureKey(psiMethod);
if (sigKey == -1) {
return -1;
}
- return myCompoundKeyEnumerator.enumerate(new int[]{mkDirectionKey(direction), sigKey});
-
+ long directionKey = mkDirectionKey(direction);
+ return sigKey * SHIFT + directionKey;
}
private int mkPsiSignatureKey(@NotNull PsiMethod psiMethod) throws IOException {
@@ -228,21 +197,20 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
final int shift = isInnerClassConstructor ? 1 : 0;
final int arity = parameters.length + shift;
- int[] shortSigKey = new int[3 + arity];
+ int[] shortSigKey = new int[2 + arity];
if (returnType == null) {
shortSigKey[0] = mkPsiTypeKey(PsiType.VOID);
- shortSigKey[1] = myNamesEnumerator.enumerate("<init>");
+ shortSigKey[1] = enumerateString("<init>");
} else {
shortSigKey[0] = mkPsiTypeKey(returnType);
- shortSigKey[1] = myNamesEnumerator.enumerate(psiMethod.getName());
+ shortSigKey[1] = enumerateString(psiMethod.getName());
}
- shortSigKey[2] = arity;
if (isInnerClassConstructor) {
- shortSigKey[3] = mkPsiClassKey(outerClass, 0);
+ shortSigKey[2] = mkPsiClassKey(outerClass, 0);
}
for (int i = 0; i < parameters.length; i++) {
PsiParameter parameter = parameters[i];
- shortSigKey[3 + i + shift] = mkPsiTypeKey(parameter.getType());
+ shortSigKey[2 + i + shift] = mkPsiTypeKey(parameter.getType());
}
for (int aShortSigKey : shortSigKey) {
if (aShortSigKey == -1) {
@@ -256,9 +224,28 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
return -1;
}
sigKey[0] = classKey;
- sigKey[1] = myCompoundKeyEnumerator.enumerate(shortSigKey);
+ sigKey[1] = enumerateCompoundKey(shortSigKey);
- return myCompoundKeyEnumerator.enumerate(sigKey);
+ return enumerateCompoundKey(sigKey);
+ }
+
+ public TLongArrayList mkInOutKeys(@NotNull PsiMethod psiMethod, long primaryKey) throws IOException {
+ PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
+ TLongArrayList keys = new TLongArrayList(parameters.length * 2 + 1);
+ for (int i = 0; i < parameters.length; i++) {
+ PsiParameter parameter = parameters[i];
+ PsiType parameterType = parameter.getType();
+ if (parameterType instanceof PsiPrimitiveType) {
+ if (PsiType.BOOLEAN.equals(parameterType)) {
+ keys.add(primaryKey + mkDirectionKey(new InOut(i, Value.False)));
+ keys.add(primaryKey + mkDirectionKey(new InOut(i, Value.True)));
+ }
+ } else {
+ keys.add(primaryKey + mkDirectionKey(new InOut(i, Value.NotNull)));
+ keys.add(primaryKey + mkDirectionKey(new InOut(i, Value.Null)));
+ }
+ }
+ return keys;
}
@@ -279,17 +266,17 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
className = qname.substring(packageName.length() + 1).replace('.', '$');
}
int[] classKey = new int[2];
- classKey[0] = myNamesEnumerator.enumerate(packageName);
+ classKey[0] = enumerateString(packageName);
if (dimensions == 0) {
- classKey[1] = myNamesEnumerator.enumerate(className);
+ classKey[1] = enumerateString(className);
} else {
StringBuilder sb = new StringBuilder(className);
for (int j = 0; j < dimensions; j++) {
sb.append("[]");
}
- classKey[1] = myNamesEnumerator.enumerate(sb.toString());
+ classKey[1] = enumerateString(sb.toString());
}
- return myCompoundKeyEnumerator.enumerate(classKey);
+ return enumerateCompoundKey(classKey);
}
private int mkPsiTypeKey(PsiType psiType) throws IOException {
@@ -316,77 +303,69 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
String packageName = "";
String className = psiType.getPresentableText();
int[] classKey = new int[2];
- classKey[0] = myNamesEnumerator.enumerate(packageName);
+ classKey[0] = enumerateString(packageName);
if (dimensions == 0) {
- classKey[1] = myNamesEnumerator.enumerate(className);
+ classKey[1] = enumerateString(className);
} else {
StringBuilder sb = new StringBuilder(className);
for (int j = 0; j < dimensions; j++) {
sb.append("[]");
}
- classKey[1] = myNamesEnumerator.enumerate(sb.toString());
+ classKey[1] = enumerateString(sb.toString());
}
- return myCompoundKeyEnumerator.enumerate(classKey);
+ return enumerateCompoundKey(classKey);
}
return -1;
}
- public void addAnnotations(TIntObjectHashMap<Value> internalIdSolutions, Annotations annotations) {
-
- TIntObjectHashMap<List<String>> contractClauses = new TIntObjectHashMap<List<String>>();
- TIntObjectIterator<Value> solutionsIterator = internalIdSolutions.iterator();
+ public void addMethodAnnotations(TLongObjectHashMap<Value> internalIdSolutions, Annotations annotations, long methodKey, int arity) {
- TIntHashSet notNulls = annotations.notNulls;
- TIntObjectHashMap<String> contracts = annotations.contracts;
+ List<String> clauses = new ArrayList<String>();
+ TLongObjectIterator<Value> solutionsIterator = internalIdSolutions.iterator();
+ TLongHashSet notNulls = annotations.notNulls;
+ TLongObjectHashMap<String> contracts = annotations.contracts;
for (int i = internalIdSolutions.size(); i-- > 0;) {
solutionsIterator.advance();
- int key = Math.abs(solutionsIterator.key());
+ long key = Math.abs(solutionsIterator.key());
Value value = solutionsIterator.value();
if (value == Value.Top || value == Value.Bot) {
continue;
}
- try {
- int[] compoundKey = myCompoundKeyEnumerator.valueOf(key);
- Direction direction = extractDirection(myCompoundKeyEnumerator.valueOf(compoundKey[0]));
- if (value == Value.NotNull && (direction instanceof In || direction instanceof Out)) {
- notNulls.add(key);
- }
- else if (direction instanceof InOut) {
- compoundKey = new int[]{mkDirectionKey(new Out()), compoundKey[1]};
- try {
- int baseKey = myCompoundKeyEnumerator.enumerate(compoundKey);
- List<String> clauses = contractClauses.get(baseKey);
- if (clauses == null) {
- clauses = new ArrayList<String>();
- contractClauses.put(baseKey, clauses);
- }
- int[] sig = myCompoundKeyEnumerator.valueOf(compoundKey[1]);
- int[] shortSig = myCompoundKeyEnumerator.valueOf(sig[1]);
- int arity = shortSig[2];
- clauses.add(contractElement(arity, (InOut)direction, value));
- }
- catch (IOException e) {
- LOG.debug(e);
- }
- }
+ Direction direction = extractDirection((int)(key % SHIFT));
+ if (value == Value.NotNull && direction instanceof Out && key == methodKey) {
+ notNulls.add(key);
}
- catch (IOException e) {
- LOG.debug(e);
+ else if (direction instanceof InOut) {
+ long baseKey = key - (key % SHIFT);
+ if (baseKey == methodKey) {
+ clauses.add(contractElement(arity, (InOut)direction, value));
+ }
}
}
- TIntObjectIterator<List<String>> buildersIterator = contractClauses.iterator();
- for (int i = contractClauses.size(); i-- > 0;) {
- buildersIterator.advance();
- int key = buildersIterator.key();
- if (!notNulls.contains(key)) {
- List<String> clauses = buildersIterator.value();
- Collections.sort(clauses);
- StringBuilder sb = new StringBuilder("\"");
- StringUtil.join(clauses, ";", sb);
- sb.append('"');
- contracts.put(key, sb.toString().intern());
+ if (!notNulls.contains(methodKey) && !clauses.isEmpty()) {
+ Collections.sort(clauses);
+ StringBuilder sb = new StringBuilder("\"");
+ StringUtil.join(clauses, ";", sb);
+ sb.append('"');
+ contracts.put(methodKey, sb.toString().intern());
+ }
+ }
+
+ public void addParameterAnnotations(TLongObjectHashMap<Value> internalIdSolutions, Annotations annotations) {
+ TLongObjectIterator<Value> solutionsIterator = internalIdSolutions.iterator();
+ TLongHashSet notNulls = annotations.notNulls;
+ for (int i = internalIdSolutions.size(); i-- > 0;) {
+ solutionsIterator.advance();
+ long key = Math.abs(solutionsIterator.key());
+ Value value = solutionsIterator.value();
+ if (value == Value.Top || value == Value.Bot) {
+ continue;
+ }
+ Direction direction = extractDirection((int)(key % SHIFT));
+ if (value == Value.NotNull && (direction instanceof In || direction instanceof Out)) {
+ notNulls.add(key);
}
}
}
@@ -418,68 +397,4 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
return sb.toString();
}
- public int getVersion() {
- return version;
- }
-
- private static class IntArrayKeyDescriptor implements KeyDescriptor<int[]> {
-
- @Override
- public void save(@NotNull DataOutput out, int[] value) throws IOException {
- DataInputOutputUtil.writeINT(out, value.length);
- for (int i : value) {
- DataInputOutputUtil.writeINT(out, i);
- }
- }
-
- @Override
- public int[] read(@NotNull DataInput in) throws IOException {
- int[] value = new int[DataInputOutputUtil.readINT(in)];
- for (int i = 0; i < value.length; i++) {
- value[i] = DataInputOutputUtil.readINT(in);
- }
- return value;
- }
-
- @Override
- public int getHashCode(int[] value) {
- return Arrays.hashCode(value);
- }
-
- @Override
- public boolean isEqual(int[] val1, int[] val2) {
- return Arrays.equals(val1, val2);
- }
- }
-
- private static class IntArrayPersistentEnumerator extends PersistentEnumeratorDelegate<int[]> {
- private final CachingEnumerator<int[]> myCache;
-
- public IntArrayPersistentEnumerator(File compoundKeysFile, IntArrayKeyDescriptor descriptor) throws IOException {
- super(compoundKeysFile, descriptor, 1024 * 4);
- myCache = new CachingEnumerator<int[]>(new DataEnumerator<int[]>() {
- @Override
- public int enumerate(@Nullable int[] value) throws IOException {
- return IntArrayPersistentEnumerator.super.enumerate(value);
- }
-
- @Nullable
- @Override
- public int[] valueOf(int idx) throws IOException {
- return IntArrayPersistentEnumerator.super.valueOf(idx);
- }
- }, descriptor);
- }
-
- @Override
- public int enumerate(@Nullable int[] value) throws IOException {
- return myCache.enumerate(value);
- }
-
- @Nullable
- @Override
- public int[] valueOf(int idx) throws IOException {
- return myCache.valueOf(idx);
- }
- }
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverterImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverterImpl.java
new file mode 100644
index 000000000000..067cc743679e
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverterImpl.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.bytecodeAnalysis;
+
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.util.ThrowableComputable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.io.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.*;
+import java.io.DataOutputStream;
+import java.util.Arrays;
+
+import static com.intellij.codeInspection.bytecodeAnalysis.ProjectBytecodeAnalysis.LOG;
+
+/**
+ * @author lambdamix
+ */
+public class BytecodeAnalysisConverterImpl extends BytecodeAnalysisConverter {
+ private static final int LOGIC_VERSION = 1;
+ private static final String ENUMERATORS_VERSION_KEY = "BytecodeAnalysisConverter.Enumerators";
+
+ private File myVersionFile;
+ private PersistentStringEnumerator myNamesEnumerator;
+ private PersistentEnumeratorDelegate<int[]> myCompoundKeyEnumerator;
+ private int version;
+
+ @Override
+ public void initComponent() {
+
+ // suffix as an indicator of version
+ final File keysDir = new File(PathManager.getIndexRoot(), "bytecodekeys");
+ final File namesFile = new File(keysDir, "names" + LOGIC_VERSION);
+ final File compoundKeysFile = new File(keysDir, "compound" + LOGIC_VERSION);
+ myVersionFile = new File(keysDir, "version" + LOGIC_VERSION);
+
+ version = PropertiesComponent.getInstance().getOrInitInt(ENUMERATORS_VERSION_KEY, 0);
+ if (ApplicationManager.getApplication().isUnitTestMode()) {
+ version = _readVersion();
+ }
+
+ if (!namesFile.exists() || !compoundKeysFile.exists() || !myVersionFile.exists()) {
+ LOG.info("No enumerators detected, re-initialization of enumerators.");
+ IOUtil.deleteAllFilesStartingWith(keysDir);
+ version++;
+ }
+
+ try {
+ IOUtil.openCleanOrResetBroken(new ThrowableComputable<Void, IOException>() {
+ @Override
+ public Void compute() throws IOException {
+ myNamesEnumerator = new PersistentStringEnumerator(namesFile, true);
+ myCompoundKeyEnumerator = new IntArrayPersistentEnumerator(compoundKeysFile, new IntArrayKeyDescriptor());
+ return null;
+ }
+ }, new Runnable() {
+ @Override
+ public void run() {
+ LOG.info("Error during initialization of enumerators in bytecode analysis. Re-initializing.");
+ IOUtil.deleteAllFilesStartingWith(keysDir);
+ version++;
+ }
+ });
+ }
+ catch (IOException e) {
+ LOG.error("Re-initialization of enumerators in bytecode analysis failed.", e);
+ }
+ PropertiesComponent.getInstance().setValue(ENUMERATORS_VERSION_KEY, String.valueOf(version));
+ _saveVersion();
+ }
+
+ @Override
+ public void disposeComponent() {
+ try {
+ myNamesEnumerator.close();
+ myCompoundKeyEnumerator.close();
+ }
+ catch (IOException e) {
+ LOG.debug(e);
+ }
+ }
+
+ public int _readVersion() {
+ try {
+ final DataInputStream is = new DataInputStream(new FileInputStream(myVersionFile));
+ try {
+ return is.readInt();
+ }
+ finally {
+ is.close();
+ }
+ }
+ catch (FileNotFoundException ignored) {
+ }
+ catch (IOException ignored) {
+ }
+ return 0;
+ }
+
+ private void _saveVersion() {
+ try {
+ FileUtil.createIfDoesntExist(myVersionFile);
+ final DataOutputStream os = new DataOutputStream(new FileOutputStream(myVersionFile));
+ try {
+ os.writeInt(version);
+ }
+ finally {
+ os.close();
+ }
+ }
+ catch (IOException ignored) {
+ }
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ @Override
+ protected int enumerateString(@NotNull String s) throws IOException {
+ return myNamesEnumerator.enumerate(s);
+ }
+
+ @Override
+ protected int enumerateCompoundKey(@NotNull int[] key) throws IOException {
+ return myCompoundKeyEnumerator.enumerate(key);
+ }
+
+ private static class IntArrayKeyDescriptor implements KeyDescriptor<int[]>, DifferentSerializableBytesImplyNonEqualityPolicy {
+
+ @Override
+ public void save(@NotNull DataOutput out, int[] value) throws IOException {
+ DataInputOutputUtil.writeINT(out, value.length);
+ for (int i : value) {
+ DataInputOutputUtil.writeINT(out, i);
+ }
+ }
+
+ @Override
+ public int[] read(@NotNull DataInput in) throws IOException {
+ int[] value = new int[DataInputOutputUtil.readINT(in)];
+ for (int i = 0; i < value.length; i++) {
+ value[i] = DataInputOutputUtil.readINT(in);
+ }
+ return value;
+ }
+
+ @Override
+ public int getHashCode(int[] value) {
+ return Arrays.hashCode(value);
+ }
+
+ @Override
+ public boolean isEqual(int[] val1, int[] val2) {
+ return Arrays.equals(val1, val2);
+ }
+ }
+
+ private static class IntArrayPersistentEnumerator extends PersistentEnumeratorDelegate<int[]> {
+ private final CachingEnumerator<int[]> myCache;
+
+ public IntArrayPersistentEnumerator(File compoundKeysFile, IntArrayKeyDescriptor descriptor) throws IOException {
+ super(compoundKeysFile, descriptor, 1024 * 4);
+ myCache = new CachingEnumerator<int[]>(new DataEnumerator<int[]>() {
+ @Override
+ public int enumerate(@Nullable int[] value) throws IOException {
+ return IntArrayPersistentEnumerator.super.enumerate(value);
+ }
+
+ @Nullable
+ @Override
+ public int[] valueOf(int idx) throws IOException {
+ return IntArrayPersistentEnumerator.super.valueOf(idx);
+ }
+ }, descriptor);
+ }
+
+ @Override
+ public int enumerate(@Nullable int[] value) throws IOException {
+ return myCache.enumerate(value);
+ }
+
+ @Nullable
+ @Override
+ public int[] valueOf(int idx) throws IOException {
+ return myCache.valueOf(idx);
+ }
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java
index 6a4b32783c95..297b2b694c62 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java
@@ -19,31 +19,29 @@ import com.intellij.ide.highlighter.JavaClassFileType;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileWithId;
import com.intellij.util.SystemProperties;
import com.intellij.util.indexing.*;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.DataInputOutputUtil;
-import com.intellij.util.io.EnumeratorIntegerDescriptor;
+import com.intellij.util.io.DifferentSerializableBytesImplyNonEqualityPolicy;
import com.intellij.util.io.KeyDescriptor;
import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
/**
* @author lambdamix
*/
-public class BytecodeAnalysisIndex extends FileBasedIndexExtension<Integer, Collection<IntIdEquation>> {
- public static final ID<Integer, Collection<IntIdEquation>> NAME = ID.create("bytecodeAnalysis");
+public class BytecodeAnalysisIndex extends FileBasedIndexExtension<Long, IdEquation> {
+ public static final ID<Long, IdEquation> NAME = ID.create("bytecodeAnalysis");
private final EquationExternalizer myExternalizer = new EquationExternalizer();
- private static final DataIndexer<Integer, Collection<IntIdEquation>, FileContent> INDEXER =
+ private static final DataIndexer<Long, IdEquation, FileContent> INDEXER =
new ClassDataIndexer(BytecodeAnalysisConverter.getInstance());
+ private static final SmartLongKeyDescriptor KEY_DESCRIPTOR = new SmartLongKeyDescriptor();
- private static final int ourInternalVersion = 2;
+ private static final int ourInternalVersion = 3;
private static boolean ourEnabled = SystemProperties.getBooleanProperty("idea.enable.bytecode.contract.inference", isEnabledByDefault());
private static boolean isEnabledByDefault() {
@@ -51,31 +49,27 @@ public class BytecodeAnalysisIndex extends FileBasedIndexExtension<Integer, Coll
return application.isInternal() || application.isUnitTestMode();
}
- public static int indexKey(VirtualFile file, boolean parameters) {
- return (file instanceof VirtualFileWithId ? ((VirtualFileWithId)file).getId() * 2 : -2) + (parameters ? 1 : 0);
- }
-
@NotNull
@Override
- public ID<Integer, Collection<IntIdEquation>> getName() {
+ public ID<Long, IdEquation> getName() {
return NAME;
}
@NotNull
@Override
- public DataIndexer<Integer, Collection<IntIdEquation>, FileContent> getIndexer() {
+ public DataIndexer<Long, IdEquation, FileContent> getIndexer() {
return INDEXER;
}
@NotNull
@Override
- public KeyDescriptor<Integer> getKeyDescriptor() {
- return EnumeratorIntegerDescriptor.INSTANCE;
+ public KeyDescriptor<Long> getKeyDescriptor() {
+ return KEY_DESCRIPTOR;
}
@NotNull
@Override
- public DataExternalizer<Collection<IntIdEquation>> getValueExternalizer() {
+ public DataExternalizer<IdEquation> getValueExternalizer() {
return myExternalizer;
}
@@ -100,68 +94,108 @@ public class BytecodeAnalysisIndex extends FileBasedIndexExtension<Integer, Coll
return ourInternalVersion + BytecodeAnalysisConverter.getInstance().getVersion() + (ourEnabled ? 0xFF : 0);
}
- public static class EquationExternalizer implements DataExternalizer<Collection<IntIdEquation>> {
+ public static class EquationExternalizer implements DataExternalizer<IdEquation>, DifferentSerializableBytesImplyNonEqualityPolicy {
@Override
- public void save(@NotNull DataOutput out, Collection<IntIdEquation> equations) throws IOException {
- DataInputOutputUtil.writeINT(out, equations.size());
-
- for (IntIdEquation equation : equations) {
- out.writeInt(equation.id);
- IntIdResult rhs = equation.rhs;
- if (rhs instanceof IntIdFinal) {
- IntIdFinal finalResult = (IntIdFinal)rhs;
- out.writeBoolean(true); // final flag
- DataInputOutputUtil.writeINT(out, finalResult.value.ordinal());
- } else {
- IntIdPending pendResult = (IntIdPending)rhs;
- out.writeBoolean(false); // pending flag
- DataInputOutputUtil.writeINT(out, pendResult.delta.length);
-
- for (IntIdComponent component : pendResult.delta) {
- DataInputOutputUtil.writeINT(out, component.value.ordinal());
- int[] ids = component.ids;
- DataInputOutputUtil.writeINT(out, ids.length);
- for (int id : ids) {
- out.writeInt(id);
- }
+ public void save(@NotNull DataOutput out, IdEquation equation) throws IOException {
+ long id = equation.id;
+ int sign = id > 0 ? 1 : -1;
+ id = Math.abs(id);
+ int primaryId = (int)(id / BytecodeAnalysisConverter.SHIFT);
+ int secondaryId = (int)(id % BytecodeAnalysisConverter.SHIFT);
+ out.writeInt(sign * primaryId);
+ DataInputOutputUtil.writeINT(out, secondaryId);
+ IdResult rhs = equation.rhs;
+ if (rhs instanceof IdFinal) {
+ IdFinal finalResult = (IdFinal)rhs;
+ out.writeBoolean(true); // final flag
+ DataInputOutputUtil.writeINT(out, finalResult.value.ordinal());
+ } else {
+ IdPending pendResult = (IdPending)rhs;
+ out.writeBoolean(false); // pending flag
+ DataInputOutputUtil.writeINT(out, pendResult.delta.length);
+
+ for (IntIdComponent component : pendResult.delta) {
+ DataInputOutputUtil.writeINT(out, component.value.ordinal());
+ long[] ids = component.ids;
+ DataInputOutputUtil.writeINT(out, ids.length);
+ for (long id1 : ids) {
+ sign = id1 > 0 ? 1 : -1;
+ id = Math.abs(id1);
+ primaryId = (int)(id / BytecodeAnalysisConverter.SHIFT);
+ secondaryId = (int)(id % BytecodeAnalysisConverter.SHIFT);
+ out.writeInt(sign * primaryId);
+ DataInputOutputUtil.writeINT(out, secondaryId);
}
}
}
}
@Override
- public Collection<IntIdEquation> read(@NotNull DataInput in) throws IOException {
-
- int size = DataInputOutputUtil.readINT(in);
- ArrayList<IntIdEquation> result = new ArrayList<IntIdEquation>(size);
-
- for (int x = 0; x < size; x++) {
- int equationId = in.readInt();
- boolean isFinal = in.readBoolean(); // flag
- if (isFinal) {
+ public IdEquation read(@NotNull DataInput in) throws IOException {
+ long primaryId = in.readInt();
+ int sign = primaryId > 0 ? 1 : -1;
+ primaryId = Math.abs(primaryId);
+ int secondaryId = DataInputOutputUtil.readINT(in);
+ long equationId = sign * (primaryId * BytecodeAnalysisConverter.SHIFT + secondaryId);
+ boolean isFinal = in.readBoolean(); // flag
+ if (isFinal) {
+ int ordinal = DataInputOutputUtil.readINT(in);
+ Value value = Value.values()[ordinal];
+ return new IdEquation(equationId, new IdFinal(value));
+ } else {
+
+ int sumLength = DataInputOutputUtil.readINT(in);
+ IntIdComponent[] components = new IntIdComponent[sumLength];
+
+ for (int i = 0; i < sumLength; i++) {
int ordinal = DataInputOutputUtil.readINT(in);
Value value = Value.values()[ordinal];
- result.add(new IntIdEquation(equationId, new IntIdFinal(value)));
- } else {
-
- int sumLength = DataInputOutputUtil.readINT(in);
- IntIdComponent[] components = new IntIdComponent[sumLength];
-
- for (int i = 0; i < sumLength; i++) {
- int ordinal = DataInputOutputUtil.readINT(in);
- Value value = Value.values()[ordinal];
- int componentSize = DataInputOutputUtil.readINT(in);
- int[] ids = new int[componentSize];
- for (int j = 0; j < componentSize; j++) {
- ids[j] = in.readInt();
- }
- components[i] = new IntIdComponent(value, ids);
+ int componentSize = DataInputOutputUtil.readINT(in);
+ long[] ids = new long[componentSize];
+ for (int j = 0; j < componentSize; j++) {
+ primaryId = in.readInt();
+ sign = primaryId > 0 ? 1 : -1;
+ primaryId = Math.abs(primaryId);
+ secondaryId = DataInputOutputUtil.readINT(in);
+ long id = sign * (primaryId * BytecodeAnalysisConverter.SHIFT + secondaryId);
+ ids[j] = id;
}
- result.add(new IntIdEquation(equationId, new IntIdPending(components)));
+ components[i] = new IntIdComponent(value, ids);
}
+ return new IdEquation(equationId, new IdPending(components));
}
+ }
+ }
+
+ private static class SmartLongKeyDescriptor implements KeyDescriptor<Long>, DifferentSerializableBytesImplyNonEqualityPolicy {
+ @Override
+ public void save(@NotNull DataOutput out, Long value) throws IOException {
+ long id = value.longValue();
+ int sign = id > 0 ? 1 : -1;
+ id = Math.abs(id);
+ int primaryId = (int)(id / BytecodeAnalysisConverter.SHIFT);
+ int secondaryId = (int)(id % BytecodeAnalysisConverter.SHIFT);
+ out.writeInt(primaryId * sign);
+ DataInputOutputUtil.writeINT(out, secondaryId);
+ }
+
+ @Override
+ public Long read(@NotNull DataInput in) throws IOException {
+ long primaryId = in.readInt();
+ int sign = primaryId > 0 ? 1 : -1;
+ primaryId = Math.abs(primaryId);
+ int secondaryId = DataInputOutputUtil.readINT(in);
+ return sign * (primaryId * BytecodeAnalysisConverter.SHIFT + secondaryId);
+ }
- return result;
+ @Override
+ public int getHashCode(Long value) {
+ return value.hashCode();
+ }
+
+ @Override
+ public boolean isEqual(Long val1, Long val2) {
+ return val1.longValue() == val2.longValue();
}
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java
index 5e74a8b5dbb3..9e656b98a7fb 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java
@@ -33,7 +33,7 @@ import static com.intellij.codeInspection.bytecodeAnalysis.ProjectBytecodeAnalys
/**
* @author lambdamix
*/
-public class ClassDataIndexer implements DataIndexer<Integer, Collection<IntIdEquation>, FileContent> {
+public class ClassDataIndexer implements DataIndexer<Long, IdEquation, FileContent> {
final BytecodeAnalysisConverter myConverter;
public ClassDataIndexer(BytecodeAnalysisConverter converter) {
@@ -42,25 +42,20 @@ public class ClassDataIndexer implements DataIndexer<Integer, Collection<IntIdEq
@NotNull
@Override
- public Map<Integer, Collection<IntIdEquation>> map(@NotNull FileContent inputData) {
- HashMap<Integer, Collection<IntIdEquation>> map = new HashMap<Integer, Collection<IntIdEquation>>(2);
+ public Map<Long, IdEquation> map(@NotNull FileContent inputData) {
+ HashMap<Long, IdEquation> map = new HashMap<Long, IdEquation>();
try {
ClassEquations rawEquations = processClass(new ClassReader(inputData.getContent()));
List<Equation<Key, Value>> rawParameterEquations = rawEquations.parameterEquations;
List<Equation<Key, Value>> rawContractEquations = rawEquations.contractEquations;
- Collection<IntIdEquation> idParameterEquations = new ArrayList<IntIdEquation>(rawParameterEquations.size());
- Collection<IntIdEquation> idContractEquations = new ArrayList<IntIdEquation>(rawContractEquations.size());
-
- map.put(BytecodeAnalysisIndex.indexKey(inputData.getFile(), true), idParameterEquations);
- map.put(BytecodeAnalysisIndex.indexKey(inputData.getFile(), false), idContractEquations);
-
-
for (Equation<Key, Value> rawParameterEquation: rawParameterEquations) {
- idParameterEquations.add(myConverter.convert(rawParameterEquation));
+ IdEquation equation = myConverter.convert(rawParameterEquation);
+ map.put(equation.id, equation);
}
for (Equation<Key, Value> rawContractEquation: rawContractEquations) {
- idContractEquations.add(myConverter.convert(rawContractEquation));
+ IdEquation equation = myConverter.convert(rawContractEquation);
+ map.put(equation.id, equation);
}
}
catch (ProcessCanceledException e) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Contracts.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Contracts.java
index c837b127b74b..7b6c52e75a63 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Contracts.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Contracts.java
@@ -49,7 +49,7 @@ class InOutAnalysis extends Analysis<Result<Key, Value>> {
}
@Override
- Result<Key, Value> combineResults(Result<Key, Value> delta, List<Result<Key, Value>> subResults) {
+ Result<Key, Value> combineResults(Result<Key, Value> delta, List<Result<Key, Value>> subResults) throws AnalyzerException {
Result<Key, Value> result = null;
for (Result<Key, Value> subResult : subResults) {
if (result == null) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Parameters.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Parameters.java
index 08c52c4d49b0..625eb8eed977 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Parameters.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Parameters.java
@@ -78,8 +78,9 @@ abstract class PResults {
};
static final class ConditionalNPE implements PResult {
final Set<Set<Key>> sop;
- public ConditionalNPE(Set<Set<Key>> sop) {
+ public ConditionalNPE(Set<Set<Key>> sop) throws AnalyzerException {
this.sop = sop;
+ checkLimit(sop);
}
public ConditionalNPE(Key key) {
@@ -88,9 +89,19 @@ abstract class PResults {
prod.add(key);
sop.add(prod);
}
+
+ static void checkLimit(Set<Set<Key>> sop) throws AnalyzerException {
+ int size = 0;
+ for (Set<Key> keys : sop) {
+ size += keys.size();
+ }
+ if (size > Analysis.EQUATION_SIZE_LIMIT) {
+ throw new AnalyzerException(null, "Equation size is too big");
+ }
+ }
}
- static PResult join(PResult r1, PResult r2) {
+ static PResult join(PResult r1, PResult r2) throws AnalyzerException {
if (Identity == r1) return r2;
if (Identity == r2) return r1;
if (Return == r1) return Return;
@@ -102,7 +113,7 @@ abstract class PResults {
return new ConditionalNPE(join(cnpe1.sop, cnpe2.sop));
}
- static PResult meet(PResult r1, PResult r2) {
+ static PResult meet(PResult r1, PResult r2) throws AnalyzerException {
if (Identity == r1) return r2;
if (Return == r1) return r2;
if (Return == r2) return r1;
@@ -130,7 +141,7 @@ class NonNullInAnalysis extends Analysis<PResult> {
}
@Override
- PResult combineResults(PResult delta, List<PResult> subResults) {
+ PResult combineResults(PResult delta, List<PResult> subResults) throws AnalyzerException {
PResult subResult = Identity;
for (PResult sr : subResults) {
subResult = join(subResult, sr);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ProjectBytecodeAnalysis.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ProjectBytecodeAnalysis.java
index 86b9dd101fd9..23d9d5a9e1c5 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ProjectBytecodeAnalysis.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ProjectBytecodeAnalysis.java
@@ -15,34 +15,31 @@
*/
package com.intellij.codeInspection.bytecodeAnalysis;
-import com.intellij.ProjectTopics;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ContentIterator;
-import com.intellij.openapi.roots.ModuleRootAdapter;
-import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.ModificationTracker;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.LongStack;
import com.intellij.util.indexing.FileBasedIndex;
-import com.intellij.util.messages.MessageBusConnection;
-import gnu.trove.TIntHashSet;
-import gnu.trove.TIntObjectHashMap;
+import gnu.trove.TLongArrayList;
+import gnu.trove.TLongHashSet;
+import gnu.trove.TLongObjectHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
-import java.util.Collection;
+import java.util.List;
/**
* @author lambdamix
@@ -50,93 +47,15 @@ import java.util.Collection;
public class ProjectBytecodeAnalysis {
public static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.bytecodeAnalysis");
public static final Key<Boolean> INFERRED_ANNOTATION = Key.create("INFERRED_ANNOTATION");
+ public static final int EQUATIONS_LIMIT = 1000;
private final Project myProject;
- private volatile Annotations myAnnotations = null;
-
public static ProjectBytecodeAnalysis getInstance(@NotNull Project project) {
return ServiceManager.getService(project, ProjectBytecodeAnalysis.class);
}
public ProjectBytecodeAnalysis(Project project) {
myProject = project;
- final MessageBusConnection connection = myProject.getMessageBus().connect();
- connection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
- @Override
- public void rootsChanged(ModuleRootEvent event) {
- unloadAnnotations();
- }
- });
- }
-
- private void loadAnnotations() {
- Annotations annotations = new Annotations();
- loadParameterAnnotations(annotations);
- loadContractAnnotations(annotations);
- myAnnotations = annotations;
- LOG.debug("NotNull annotations: " + myAnnotations.notNulls.size());
- LOG.debug("Contract annotations: " + myAnnotations.contracts.size());
- }
-
- private void unloadAnnotations() {
- myAnnotations = null;
- LOG.debug("unloaded");
- }
-
- private void loadParameterAnnotations(Annotations annotations) {
- LOG.debug("initializing parameter annotations");
- final IntIdSolver solver = new IntIdSolver(new ELattice<Value>(Value.NotNull, Value.Top));
-
- processValues(true, new FileBasedIndex.ValueProcessor<Collection<IntIdEquation>>() {
- @Override
- public boolean process(VirtualFile file, Collection<IntIdEquation> value) {
- for (IntIdEquation intIdEquation : value) {
- solver.addEquation(intIdEquation);
- }
- return true;
- }
- });
-
- LOG.debug("parameter equations are constructed");
- LOG.debug("equations: " + solver.getSize());
- TIntObjectHashMap<Value> solutions = solver.solve();
- LOG.debug("parameter equations are solved");
- BytecodeAnalysisConverter.getInstance().addAnnotations(solutions, annotations);
- }
-
- private void processValues(final boolean parameters, final FileBasedIndex.ValueProcessor<Collection<IntIdEquation>> processor) {
- final GlobalSearchScope libScope = ProjectScope.getLibrariesScope(myProject);
- final FileBasedIndex index = FileBasedIndex.getInstance();
- index.iterateIndexableFiles(new ContentIterator() {
- @Override
- public boolean processFile(VirtualFile fileOrDir) {
- ProgressManager.checkCanceled();
- if (!fileOrDir.isDirectory() && libScope.contains(fileOrDir)) {
- index.processValues(BytecodeAnalysisIndex.NAME, BytecodeAnalysisIndex.indexKey(fileOrDir, parameters),
- fileOrDir, processor, GlobalSearchScope.fileScope(myProject, fileOrDir));
- }
- return false;
- }
- }, myProject, null);
- }
-
- private void loadContractAnnotations(Annotations annotations) {
- LOG.debug("initializing contract annotations");
- final IntIdSolver solver = new IntIdSolver(new ELattice<Value>(Value.Bot, Value.Top));
- processValues(false, new FileBasedIndex.ValueProcessor<Collection<IntIdEquation>>() {
- @Override
- public boolean process(VirtualFile file, Collection<IntIdEquation> value) {
- for (IntIdEquation intIdEquation : value) {
- solver.addEquation(intIdEquation);
- }
- return true;
- }
- });
- LOG.debug("contract equations are constructed");
- LOG.debug("equations: " + solver.getSize());
- TIntObjectHashMap<Value> solutions = solver.solve();
- LOG.debug("contract equations are solved");
- BytecodeAnalysisConverter.getInstance().addAnnotations(solutions, annotations);
}
@Nullable
@@ -144,11 +63,14 @@ public class ProjectBytecodeAnalysis {
if (!(listOwner instanceof PsiCompiledElement)) {
return null;
}
- if (annotationFQN.equals("org.jetbrains.annotations.NotNull")) {
- return findNotNullAnnotation(listOwner);
- }
- else if (annotationFQN.equals("org.jetbrains.annotations.Contract")) {
- return findContractAnnotation(listOwner);
+ if (annotationFQN.equals(AnnotationUtil.NOT_NULL) || annotationFQN.equals(ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT)) {
+ PsiAnnotation[] annotations = findInferredAnnotations(listOwner);
+ for (PsiAnnotation annotation : annotations) {
+ if (annotationFQN.equals(annotation.getQualifiedName())) {
+ return annotation;
+ }
+ }
+ return null;
}
else {
return null;
@@ -156,26 +78,30 @@ public class ProjectBytecodeAnalysis {
}
@NotNull
- public PsiAnnotation[] findInferredAnnotations(@NotNull PsiModifierListOwner listOwner) {
+ public PsiAnnotation[] findInferredAnnotations(@NotNull final PsiModifierListOwner listOwner) {
if (!(listOwner instanceof PsiCompiledElement)) {
return PsiAnnotation.EMPTY_ARRAY;
}
- return collectInferredAnnotations(listOwner);
+ return CachedValuesManager.getCachedValue(listOwner, new CachedValueProvider<PsiAnnotation[]>() {
+ @Nullable
+ @Override
+ public Result<PsiAnnotation[]> compute() {
+ return Result.create(collectInferredAnnotations(listOwner), listOwner);
+ }
+ });
}
- // TODO the best way to synchronize?
@NotNull
- private synchronized PsiAnnotation[] collectInferredAnnotations(PsiModifierListOwner listOwner) {
- if (myAnnotations == null) {
- loadAnnotations();
- }
+ private PsiAnnotation[] collectInferredAnnotations(PsiModifierListOwner listOwner) {
try {
- int key = getKey(listOwner);
- if (key == -1) {
+ long ownerKey = getKey(listOwner);
+ if (ownerKey == -1) {
return PsiAnnotation.EMPTY_ARRAY;
}
- boolean notNull = myAnnotations.notNulls.contains(key);
- String contractValue = myAnnotations.contracts.get(key);
+ TLongArrayList allKeys = contractKeys(listOwner, ownerKey);
+ Annotations annotations = loadAnnotations(listOwner, ownerKey, allKeys);
+ boolean notNull = annotations.notNulls.contains(ownerKey);
+ String contractValue = annotations.contracts.get(ownerKey);
if (notNull && contractValue != null) {
return new PsiAnnotation[]{
@@ -201,6 +127,11 @@ public class ProjectBytecodeAnalysis {
LOG.debug(e);
return PsiAnnotation.EMPTY_ARRAY;
}
+ catch (EquationsLimitException e) {
+ String externalName = PsiFormatUtil.getExternalName(listOwner, false, Integer.MAX_VALUE);
+ LOG.info("Too many equations for " + externalName);
+ return PsiAnnotation.EMPTY_ARRAY;
+ }
}
private PsiAnnotation getNotNullAnnotation() {
@@ -213,54 +144,15 @@ public class ProjectBytecodeAnalysis {
});
}
- @Nullable
- private synchronized PsiAnnotation findNotNullAnnotation(PsiModifierListOwner listOwner) {
- if (myAnnotations == null) {
- loadAnnotations();
- }
- try {
- int key = getKey(listOwner);
- if (key == -1) {
- return null;
- }
- return myAnnotations.notNulls.contains(key) ? getNotNullAnnotation() : null;
- }
- catch (IOException e) {
- LOG.debug(e);
- return null;
- }
- }
-
- @Nullable
- private synchronized PsiAnnotation findContractAnnotation(PsiModifierListOwner listOwner) {
- if (myAnnotations == null) {
- loadAnnotations();
- }
- try {
- int key = getKey(listOwner);
- if (key == -1) {
- return null;
- }
- String contractValue = myAnnotations.contracts.get(key);
- return contractValue != null ? createContractAnnotation(contractValue) : null;
- }
- catch (IOException e) {
- LOG.debug(e);
- return null;
- }
- }
-
public PsiAnnotation createContractAnnotation(String contractValue) {
return createAnnotationFromText("@org.jetbrains.annotations.Contract(" + contractValue + ")");
}
- public static int getKey(@NotNull PsiModifierListOwner owner) throws IOException {
+ public static long getKey(@NotNull PsiModifierListOwner owner) throws IOException {
LOG.assertTrue(owner instanceof PsiCompiledElement, owner);
-
if (owner instanceof PsiMethod) {
return BytecodeAnalysisConverter.getInstance().mkPsiKey((PsiMethod)owner, new Out());
}
-
if (owner instanceof PsiParameter) {
PsiElement parent = owner.getParent();
if (parent instanceof PsiParameterList) {
@@ -275,6 +167,80 @@ public class ProjectBytecodeAnalysis {
return -1;
}
+ public static TLongArrayList contractKeys(@NotNull PsiModifierListOwner owner, long primaryKey) throws IOException {
+ if (owner instanceof PsiMethod) {
+ TLongArrayList result = BytecodeAnalysisConverter.getInstance().mkInOutKeys((PsiMethod)owner, primaryKey);
+ result.add(primaryKey);
+ return result;
+ }
+ TLongArrayList result = new TLongArrayList(1);
+ result.add(primaryKey);
+ return result;
+ }
+
+ private Annotations loadAnnotations(@NotNull PsiModifierListOwner owner, long key, TLongArrayList allKeys)
+ throws IOException, EquationsLimitException {
+ Annotations result = new Annotations();
+ if (owner instanceof PsiParameter) {
+ final Solver solver = new Solver(new ELattice<Value>(Value.NotNull, Value.Top));
+ collectEquations(allKeys, solver);
+ TLongObjectHashMap<Value> solutions = solver.solve();
+ BytecodeAnalysisConverter.getInstance().addParameterAnnotations(solutions, result);
+ } else if (owner instanceof PsiMethod) {
+ final Solver solver = new Solver(new ELattice<Value>(Value.Bot, Value.Top));
+ collectEquations(allKeys, solver);
+ TLongObjectHashMap<Value> solutions = solver.solve();
+ BytecodeAnalysisConverter.getInstance().addMethodAnnotations(solutions, result, key,
+ ((PsiMethod)owner).getParameterList().getParameters().length);
+ }
+ return result;
+ }
+
+ private void collectEquations(TLongArrayList keys, Solver solver) throws EquationsLimitException {
+ GlobalSearchScope librariesScope = ProjectScope.getLibrariesScope(myProject);
+ TLongHashSet queued = new TLongHashSet();
+ LongStack queue = new LongStack();
+
+ for (int i = 0; i < keys.size(); i++) {
+ long key = keys.get(i);
+ queue.push(key);
+ queued.add(key);
+ // stable/unstable
+ queue.push(-key);
+ queued.add(-key);
+ }
+
+ FileBasedIndex index = FileBasedIndex.getInstance();
+ while (!queue.empty()) {
+ if (queued.size() > EQUATIONS_LIMIT) {
+ throw new EquationsLimitException();
+ }
+ ProgressManager.checkCanceled();
+ List<IdEquation> equations = index.getValues(BytecodeAnalysisIndex.NAME, queue.pop(), librariesScope);
+ for (IdEquation equation : equations) {
+ IdResult rhs = equation.rhs;
+ solver.addEquation(equation);
+ if (rhs instanceof IdPending) {
+ IdPending intIdPending = (IdPending)rhs;
+ for (IntIdComponent component : intIdPending.delta) {
+ for (long depKey : component.ids) {
+ if (!queued.contains(depKey)) {
+ queue.push(depKey);
+ queued.add(depKey);
+ }
+ // stable/unstable
+ long swapped = -depKey;
+ if (!queued.contains(swapped)) {
+ queue.push(swapped);
+ queued.add(swapped);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
@NotNull
private PsiAnnotation createAnnotationFromText(@NotNull final String text) throws IncorrectOperationException {
PsiAnnotation annotation = JavaPsiFacade.getElementFactory(myProject).createAnnotationFromText(text, null);
@@ -285,7 +251,9 @@ public class ProjectBytecodeAnalysis {
class Annotations {
// @NotNull keys
- final TIntHashSet notNulls = new TIntHashSet();
+ final TLongHashSet notNulls = new TLongHashSet();
// @Contracts
- final TIntObjectHashMap<String> contracts = new TIntObjectHashMap<String>();
+ final TLongObjectHashMap<String> contracts = new TLongObjectHashMap<String>();
}
+
+class EquationsLimitException extends Exception {}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java
index 47c97790d102..1dec1de8a606 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java
@@ -15,10 +15,12 @@
*/
package com.intellij.codeInspection.bytecodeAnalysis;
-import com.intellij.util.containers.IntStack;
-import com.intellij.util.containers.IntToIntSetMap;
-import gnu.trove.TIntObjectHashMap;
+import com.intellij.util.containers.LongStack;
+import gnu.trove.TLongHashSet;
+import gnu.trove.TLongIterator;
+import gnu.trove.TLongObjectHashMap;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
import java.util.*;
@@ -49,9 +51,9 @@ final class ELattice<T extends Enum<T>> {
// component specialized for ints
final class IntIdComponent {
Value value;
- final int[] ids;
+ final long[] ids;
- IntIdComponent(Value value, int[] ids) {
+ IntIdComponent(Value value, long[] ids) {
this.value = value;
this.ids = ids;
}
@@ -74,7 +76,7 @@ final class IntIdComponent {
return value.ordinal() + Arrays.hashCode(ids);
}
- public boolean remove(int id) {
+ public boolean remove(long id) {
return IdUtils.remove(ids, id);
}
@@ -89,18 +91,18 @@ final class IntIdComponent {
class IdUtils {
// removed value
- static final int nullId = 0;
+ static final long nullId = 0;
- static boolean contains(int[] ids, int id) {
- for (int id1 : ids) {
+ static boolean contains(long[] ids, int id) {
+ for (long id1 : ids) {
if (id1 == id) return true;
}
return false;
}
- static boolean isEmpty(int[] ids) {
- for (int id : ids) {
+ static boolean isEmpty(long[] ids) {
+ for (long id : ids) {
if (id != nullId) return false;
}
return true;
@@ -117,7 +119,7 @@ class IdUtils {
return result;
}
- static boolean remove(int[] ids, int id) {
+ static boolean remove(long[] ids, long id) {
boolean removed = false;
for (int i = 0; i < ids.length; i++) {
if (ids[i] == id) {
@@ -137,7 +139,7 @@ class ResultUtil<Id, T extends Enum<T>> {
top = lattice.top;
}
- Result<Id, T> join(Result<Id, T> r1, Result<Id, T> r2) {
+ Result<Id, T> join(Result<Id, T> r1, Result<Id, T> r2) throws AnalyzerException {
if (r1 instanceof Final && ((Final) r1).value == top) {
return r1;
}
@@ -166,8 +168,19 @@ class ResultUtil<Id, T extends Enum<T>> {
Set<Product<Id, T>> sum = new HashSet<Product<Id, T>>();
sum.addAll(pending1.sum);
sum.addAll(pending2.sum);
+ checkLimit(sum);
return new Pending<Id, T>(sum);
}
+
+ private void checkLimit(Set<Product<Id, T>> sum) throws AnalyzerException {
+ int size = 0;
+ for (Product<Id, T> prod : sum) {
+ size += prod.ids.size();
+ }
+ if (size > Analysis.EQUATION_SIZE_LIMIT) {
+ throw new AnalyzerException(null, "Equation size is too big");
+ }
+ }
}
final class Product<K, V> {
@@ -222,11 +235,11 @@ final class Pending<Id, T> implements Result<Id, T> {
}
-interface IntIdResult {}
+interface IdResult {}
// this just wrapper, no need for this really
-final class IntIdFinal implements IntIdResult {
+final class IdFinal implements IdResult {
final Value value;
- public IntIdFinal(Value value) {
+ public IdFinal(Value value) {
this.value = value;
}
@@ -235,7 +248,7 @@ final class IntIdFinal implements IntIdResult {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
- IntIdFinal that = (IntIdFinal)o;
+ IdFinal that = (IdFinal)o;
if (value != that.value) return false;
@@ -253,19 +266,19 @@ final class IntIdFinal implements IntIdResult {
}
}
-final class IntIdPending implements IntIdResult {
+final class IdPending implements IdResult {
final IntIdComponent[] delta;
- IntIdPending(IntIdComponent[] delta) {
+ IdPending(IntIdComponent[] delta) {
this.delta = delta;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof IntIdPending)) return false;
- IntIdPending pending = (IntIdPending)o;
- return !Arrays.equals(delta, pending.delta);
+ if (!(o instanceof IdPending)) return false;
+ IdPending pending = (IdPending)o;
+ return Arrays.equals(delta, pending.delta);
}
@Override
@@ -273,20 +286,20 @@ final class IntIdPending implements IntIdResult {
return Arrays.hashCode(delta);
}
- IntIdPending copy() {
+ IdPending copy() {
IntIdComponent[] delta1 = new IntIdComponent[delta.length];
for (int i = 0; i < delta.length; i++) {
delta1[i] = delta[i].copy();
}
- return new IntIdPending(delta1);
+ return new IdPending(delta1);
}
}
-final class IntIdEquation {
- final int id;
- final IntIdResult rhs;
+final class IdEquation {
+ final long id;
+ final IdResult rhs;
- IntIdEquation(int id, IntIdResult rhs) {
+ IdEquation(long id, IdResult rhs) {
this.id = id;
this.rhs = rhs;
}
@@ -294,9 +307,9 @@ final class IntIdEquation {
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof IntIdEquation)) return false;
+ if (!(o instanceof IdEquation)) return false;
- IntIdEquation equation = (IntIdEquation)o;
+ IdEquation equation = (IdEquation)o;
if (id != equation.id) return false;
if (!rhs.equals(equation.rhs)) return false;
@@ -306,9 +319,7 @@ final class IntIdEquation {
@Override
public int hashCode() {
- int result = id;
- result = 31 * result + rhs.hashCode();
- return result;
+ return 31 * ((int)(id ^ (id >>> 32))) + rhs.hashCode();
}
}
@@ -337,41 +348,46 @@ final class Equation<Id, T> {
}
}
-final class IntIdSolver {
+final class Solver {
private int size = 0;
private final ELattice<Value> lattice;
- private final IntToIntSetMap dependencies = new IntToIntSetMap(10000, 0.5f);
- private final TIntObjectHashMap<IntIdPending> pending = new TIntObjectHashMap<IntIdPending>();
- private final TIntObjectHashMap<Value> solved = new TIntObjectHashMap<Value>();
- private final IntStack moving = new IntStack();
+ private final TLongObjectHashMap<TLongHashSet> dependencies = new TLongObjectHashMap<TLongHashSet>();
+ private final TLongObjectHashMap<IdPending> pending = new TLongObjectHashMap<IdPending>();
+ private final TLongObjectHashMap<Value> solved = new TLongObjectHashMap<Value>();
+ private final LongStack moving = new LongStack();
int getSize() {
return size;
}
- IntIdSolver(ELattice<Value> lattice) {
+ Solver(ELattice<Value> lattice) {
this.lattice = lattice;
}
- void addEquation(IntIdEquation equation) {
+ void addEquation(IdEquation equation) {
size ++;
- IntIdResult rhs = equation.rhs;
- if (rhs instanceof IntIdFinal) {
- solved.put(equation.id, ((IntIdFinal) rhs).value);
+ IdResult rhs = equation.rhs;
+ if (rhs instanceof IdFinal) {
+ solved.put(equation.id, ((IdFinal) rhs).value);
moving.push(equation.id);
- } else if (rhs instanceof IntIdPending) {
- IntIdPending pendResult = ((IntIdPending)rhs).copy();
- IntIdResult norm = normalize(pendResult.delta);
- if (norm instanceof IntIdFinal) {
- solved.put(equation.id, ((IntIdFinal) norm).value);
+ } else if (rhs instanceof IdPending) {
+ IdPending pendResult = ((IdPending)rhs).copy();
+ IdResult norm = normalize(pendResult.delta);
+ if (norm instanceof IdFinal) {
+ solved.put(equation.id, ((IdFinal) norm).value);
moving.push(equation.id);
}
else {
- IntIdPending pendResult1 = ((IntIdPending)rhs).copy();
+ IdPending pendResult1 = ((IdPending)rhs).copy();
for (IntIdComponent component : pendResult1.delta) {
- for (int trigger : component.ids) {
- dependencies.addOccurence(trigger, equation.id);
+ for (long trigger : component.ids) {
+ TLongHashSet set = dependencies.get(trigger);
+ if (set == null) {
+ set = new TLongHashSet();
+ dependencies.put(trigger, set);
+ }
+ set.add(equation.id);
}
pending.put(equation.id, pendResult1);
}
@@ -379,31 +395,35 @@ final class IntIdSolver {
}
}
- TIntObjectHashMap<Value> solve() {
+ TLongObjectHashMap<Value> solve() {
while (!moving.empty()) {
- int id = moving.pop();
+ long id = moving.pop();
Value value = solved.get(id);
boolean stable = id > 0;
- int[] pIds = stable ? new int[]{id, -id} : new int[]{-id, id};
+ long[] pIds = stable ? new long[]{id, -id} : new long[]{-id, id};
Value[] pVals = stable ? new Value[]{value, value} : new Value[]{value, lattice.top};
for (int i = 0; i < pIds.length; i++) {
- int pId = pIds[i];
+ long pId = pIds[i];
Value pVal = pVals[i];
- // todo - remove
- int[] dIds = dependencies.get(pId);
- for (int dId : dIds) {
- IntIdPending pend = pending.remove(dId);
+ TLongHashSet dIds = dependencies.get(pId);
+ if (dIds == null) {
+ continue;
+ }
+ TLongIterator dIdsIterator = dIds.iterator();
+ while (dIdsIterator.hasNext()) {
+ long dId = dIdsIterator.next();
+ IdPending pend = pending.remove(dId);
if (pend != null) {
- IntIdResult pend1 = substitute(pend, pId, pVal);
- if (pend1 instanceof IntIdFinal) {
- IntIdFinal fi = (IntIdFinal)pend1;
+ IdResult pend1 = substitute(pend, pId, pVal);
+ if (pend1 instanceof IdFinal) {
+ IdFinal fi = (IdFinal)pend1;
solved.put(dId, fi.value);
moving.push(dId);
}
else {
- pending.put(dId, (IntIdPending)pend1);
+ pending.put(dId, (IdPending)pend1);
}
}
}
@@ -414,7 +434,7 @@ final class IntIdSolver {
}
// substitute id -> value into pending
- IntIdResult substitute(IntIdPending pending, int id, Value value) {
+ IdResult substitute(IdPending pending, long id, Value value) {
IntIdComponent[] sum = pending.delta;
for (IntIdComponent intIdComponent : sum) {
if (intIdComponent.remove(id)) {
@@ -424,7 +444,7 @@ final class IntIdSolver {
return normalize(sum);
}
- IntIdResult normalize(IntIdComponent[] sum) {
+ IdResult normalize(IntIdComponent[] sum) {
Value acc = lattice.bot;
boolean computableNow = true;
for (IntIdComponent prod : sum) {
@@ -434,7 +454,7 @@ final class IntIdSolver {
computableNow = false;
}
}
- return (acc == lattice.top || computableNow) ? new IntIdFinal(acc) : new IntIdPending(sum);
+ return (acc == lattice.top || computableNow) ? new IdFinal(acc) : new IdPending(sum);
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
index a1c908837ad0..bd207e58a0fe 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
@@ -71,7 +71,23 @@ class ContractInferenceInterpreter {
if (statements.length == 1) {
if (statements[0] instanceof PsiReturnStatement) {
List<MethodContract> result = handleDelegation(((PsiReturnStatement)statements[0]).getReturnValue(), false);
- if (result != null) return result;
+ if (result != null) {
+ PsiTypeElement typeElement = myMethod.getReturnTypeElement();
+ final boolean returningObject = typeElement == null || !(typeElement.getType() instanceof PsiClassType);
+ return ContainerUtil.findAll(result, new Condition<MethodContract>() {
+ @Override
+ public boolean value(MethodContract contract) {
+ if ((contract.returnValue == NULL_VALUE || contract.returnValue == NOT_NULL_VALUE) && returningObject) {
+ return false;
+ }
+ if ((contract.returnValue == TRUE_VALUE || contract.returnValue == FALSE_VALUE) && !returningObject) {
+ return false;
+ }
+
+ return true;
+ }
+ });
+ }
}
else if (statements[0] instanceof PsiExpressionStatement && ((PsiExpressionStatement)statements[0]).getExpression() instanceof PsiMethodCallExpression) {
List<MethodContract> result = handleDelegation(((PsiExpressionStatement)statements[0]).getExpression(), false);
@@ -132,6 +148,9 @@ class ContractInferenceInterpreter {
}
else {
answer = withConstraint(answer, paramIndex, argConstraint);
+ if (answer == null) {
+ return null;
+ }
}
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/MethodContract.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/MethodContract.java
index 691c2f00d985..1167210f917e 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/MethodContract.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/MethodContract.java
@@ -89,10 +89,16 @@ public class MethodContract {
throw new ParseException("A contract clause must be in form arg1, ..., argN -> return-value");
}
- String[] argStrings = clause.substring(0, arrowIndex).split(",");
- ValueConstraint[] args = new ValueConstraint[argStrings.length];
- for (int i = 0; i < args.length; i++) {
- args[i] = parseConstraint(argStrings[i]);
+ String beforeArrow = clause.substring(0, arrowIndex);
+ ValueConstraint[] args;
+ if (StringUtil.isNotEmpty(beforeArrow)) {
+ String[] argStrings = beforeArrow.split(",");
+ args = new ValueConstraint[argStrings.length];
+ for (int i = 0; i < args.length; i++) {
+ args[i] = parseConstraint(argStrings[i]);
+ }
+ } else {
+ args = new ValueConstraint[0];
}
result.add(new MethodContract(args, parseConstraint(clause.substring(arrowIndex + arrow.length()))));
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
index 013e24cbe07a..36449128b494 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
@@ -500,21 +500,19 @@ public class StandardInstructionVisitor extends InstructionVisitor {
PsiType varType = var.getVariableType();
if (!(varType instanceof PsiPrimitiveType)) return null;
+
+ if (varType == PsiType.FLOAT || varType == PsiType.DOUBLE) return null;
double minValue = varType == PsiType.BYTE ? Byte.MIN_VALUE :
varType == PsiType.SHORT ? Short.MIN_VALUE :
varType == PsiType.INT ? Integer.MIN_VALUE :
varType == PsiType.CHAR ? Character.MIN_VALUE :
- varType == PsiType.LONG ? Long.MIN_VALUE :
- varType == PsiType.FLOAT ? Float.MIN_VALUE :
- Double.MIN_VALUE;
+ Long.MIN_VALUE;
double maxValue = varType == PsiType.BYTE ? Byte.MAX_VALUE :
varType == PsiType.SHORT ? Short.MAX_VALUE :
varType == PsiType.INT ? Integer.MAX_VALUE :
varType == PsiType.CHAR ? Character.MAX_VALUE :
- varType == PsiType.LONG ? Long.MAX_VALUE :
- varType == PsiType.FLOAT ? Float.MAX_VALUE :
- Double.MAX_VALUE;
+ Long.MAX_VALUE;
return checkComparisonWithKnownRange(instruction, runner, memState, opSign, comparedWith, minValue, maxValue);
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/xml/DeprecatedClassUsageInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/xml/DeprecatedClassUsageInspection.java
index 0a914c0d4477..8c9e4a72dfef 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/xml/DeprecatedClassUsageInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/xml/DeprecatedClassUsageInspection.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,7 +20,6 @@ import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.XmlSuppressableInspectionTool;
import com.intellij.codeInspection.deprecation.DeprecationInspection;
import com.intellij.psi.*;
-import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
@@ -46,11 +45,6 @@ public class DeprecatedClassUsageInspection extends XmlSuppressableInspectionToo
}
@Override
- public void visitXmlAttribute(XmlAttribute attribute) {
- checkReferences(attribute, holder);
- }
-
- @Override
public void visitXmlAttributeValue(XmlAttributeValue value) {
checkReferences(value, holder);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java
index b60094ffbd6f..ad53d9484959 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java
@@ -138,8 +138,8 @@ public class PreferByKindWeigher extends LookupElementWeigher {
qualifiedWithField,
qualifiedWithGetter,
superMethodParameters,
- expectedTypeConstant,
field,
+ expectedTypeConstant,
getter,
normal,
collectionFactory,
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodQualifierFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodQualifierFix.java
index ff851372e208..4ab9d43fbc1d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodQualifierFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodQualifierFix.java
@@ -69,10 +69,14 @@ public class AddMethodQualifierFix implements IntentionAction {
if (element == null || !element.isValid()) {
return false;
}
+ return getOrFindCandidates().size() != 0;
+ }
+
+ private synchronized List<PsiVariable> getOrFindCandidates() {
if (myCandidates == null) {
findCandidates();
}
- return myCandidates.size() != 0;
+ return myCandidates;
}
private void findCandidates() {
@@ -84,6 +88,9 @@ public class AddMethodQualifierFix implements IntentionAction {
}
for (final PsiVariable var : CreateFromUsageUtils.guessMatchingVariables(methodCallElement)) {
+ if (var.getName() == null) {
+ continue;
+ }
final PsiType type = var.getType();
if (!(type instanceof PsiClassType)) {
continue;
@@ -132,7 +139,7 @@ public class AddMethodQualifierFix implements IntentionAction {
@NotNull
@Override
public String getTextFor(final PsiVariable value) {
- return ObjectUtils.assertNotNull(value.getName());
+ return value.getName();
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AnonymousTargetClassPreselectionUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AnonymousTargetClassPreselectionUtil.java
new file mode 100644
index 000000000000..421c43cabe88
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AnonymousTargetClassPreselectionUtil.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.daemon.impl.quickfix;
+
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.psi.PsiAnonymousClass;
+import com.intellij.psi.PsiClass;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+public class AnonymousTargetClassPreselectionUtil {
+ private static final String PRESELECT_ANONYMOUS = "create.member.preselect.anonymous";
+
+ public static void rememberSelection(PsiClass aClass, PsiClass firstClass) {
+ if (firstClass instanceof PsiAnonymousClass) {
+ PropertiesComponent.getInstance().setValue(PRESELECT_ANONYMOUS, String.valueOf(aClass == firstClass));
+ }
+ }
+
+ @Nullable
+ public static PsiClass getPreselection(Collection<PsiClass> classes, PsiClass firstClass) {
+ if (firstClass instanceof PsiAnonymousClass && !PropertiesComponent.getInstance().getBoolean(PRESELECT_ANONYMOUS, true)) {
+ for (PsiClass aClass : classes) {
+ if (!(aClass instanceof PsiAnonymousClass)) {
+ return aClass;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java
index 09b83e2a489f..abe9368374e8 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java
@@ -119,7 +119,8 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction {
protected abstract PsiElement getElement();
private void chooseTargetClass(List<PsiClass> classes, final Editor editor) {
- final Project project = classes.get(0).getProject();
+ final PsiClass firstClass = classes.get(0);
+ final Project project = firstClass.getProject();
final JList list = new JBList(classes);
PsiElementListCellRenderer renderer = new PsiClassListCellRenderer();
@@ -128,12 +129,18 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction {
final PopupChooserBuilder builder = new PopupChooserBuilder(list);
renderer.installSpeedSearch(builder);
+ final PsiClass preselection = AnonymousTargetClassPreselectionUtil.getPreselection(classes, firstClass);
+ if (preselection != null) {
+ list.setSelectedValue(preselection, true);
+ }
+
Runnable runnable = new Runnable() {
@Override
public void run() {
int index = list.getSelectedIndex();
if (index < 0) return;
final PsiClass aClass = (PsiClass) list.getSelectedValue();
+ AnonymousTargetClassPreselectionUtil.rememberSelection(aClass, firstClass);
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
public void run() {
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java
index 906dfa6258de..e6991736c0e3 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java
@@ -144,6 +144,17 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> exten
RangeMarker bounds,
ReferenceData[] referenceData);
+ protected PsiElement resolveReferenceIgnoreOverriding(PsiPolyVariantReference reference) {
+ PsiElement referent = reference.resolve();
+ if (referent == null) {
+ final ResolveResult[] results = reference.multiResolve(true);
+ if (results.length > 0) {
+ referent = results[0].getElement();
+ }
+ }
+ return referent;
+ }
+
protected abstract void restoreReferences(ReferenceData[] referenceData,
TRef[] refs);
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java
index 51edddd250aa..76be78b7932d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java
@@ -88,7 +88,8 @@ public class JavaCopyPasteReferenceProcessor extends CopyPasteReferenceProcessor
}
else {
if (reference instanceof PsiReferenceExpression) {
- PsiElement referent = reference.resolve();
+ PsiElement referent = resolveReferenceIgnoreOverriding(reference);
+
if (!(referent instanceof PsiNamedElement)
|| !data.staticMemberName.equals(((PsiNamedElement)referent).getName())
|| !(referent instanceof PsiMember)
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCatchBodyFixer.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCatchBodyFixer.java
index 1d4d281aea68..08e06283d4a5 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCatchBodyFixer.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCatchBodyFixer.java
@@ -36,7 +36,7 @@ public class MissingCatchBodyFixer implements Fixer {
final Document doc = editor.getDocument();
PsiCodeBlock body = catchSection.getCatchBlock();
- if (body != null && startLine(doc, body) == startLine(doc, catchSection)) return;
+ if (body != null && body.getLBrace() != null && body.getRBrace() != null) return;
final PsiJavaToken rParenth = catchSection.getRParenth();
if (rParenth == null) return;
@@ -44,7 +44,4 @@ public class MissingCatchBodyFixer implements Fixer {
doc.insertString(rParenth.getTextRange().getEndOffset(), "{}");
}
- private static int startLine(Document doc, PsiElement psiElement) {
- return doc.getLineNumber(psiElement.getTextRange().getStartOffset());
- }
} \ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java
index 6bafcc00d983..884442c778cc 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java
@@ -83,6 +83,22 @@ public class PlainEnterProcessor implements EnterProcessor {
@Nullable
private static PsiCodeBlock getControlStatementBlock(int caret, PsiElement element) {
+ if (element instanceof PsiTryStatement) {
+ PsiCodeBlock tryBlock = ((PsiTryStatement)element).getTryBlock();
+ if (tryBlock != null && caret < tryBlock.getTextRange().getEndOffset()) return tryBlock;
+
+ for (PsiCodeBlock catchBlock : ((PsiTryStatement)element).getCatchBlocks()) {
+ if (catchBlock != null && caret < catchBlock.getTextRange().getEndOffset()) return catchBlock;
+ }
+
+ return ((PsiTryStatement)element).getFinallyBlock();
+ }
+
+ if (element instanceof PsiMethod) {
+ PsiCodeBlock methodBody = ((PsiMethod)element).getBody();
+ if (methodBody != null) return methodBody;
+ }
+
PsiStatement body = null;
if (element instanceof PsiIfStatement) {
body = ((PsiIfStatement)element).getThenBranch();
@@ -102,10 +118,6 @@ public class PlainEnterProcessor implements EnterProcessor {
else if (element instanceof PsiDoWhileStatement) {
body = ((PsiDoWhileStatement)element).getBody();
}
- else if (element instanceof PsiMethod) {
- PsiCodeBlock methodBody = ((PsiMethod)element).getBody();
- if (methodBody != null) return methodBody;
- }
return body instanceof PsiBlockStatement ? ((PsiBlockStatement)body).getCodeBlock() : 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 fd85d1124171..daf2e3002dd2 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
@@ -450,18 +450,24 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
final PsiJavaCodeReferenceElement element = annotation.getNameReferenceElement();
if (element != null) {
final PsiElement resolved = element.resolve();
- if (resolved instanceof PsiClass && !AnnotationUtil.isAnnotated((PsiClass)resolved, "java.lang.annotation.Documented", false)) continue;
+ if (resolved instanceof PsiClass && !AnnotationUtil.isAnnotated((PsiClass)resolved, "java.lang.annotation.Documented", false, true)) {
+ continue;
+ }
String referenceName = element.getReferenceName();
- if (!shownAnnotations.add(referenceName)) continue;
-
- if (lastSize != buffer.length()) buffer.append(" ");
- buffer.append("@").append(referenceName);
+ if (shownAnnotations.add(referenceName) || isRepeatableAnnotation(resolved)) {
+ if (lastSize != buffer.length()) buffer.append(" ");
+ buffer.append("@").append(referenceName);
+ }
}
}
if (lastSize != buffer.length()) buffer.append(" ");
}
+ private static boolean isRepeatableAnnotation(PsiElement resolved) {
+ return resolved instanceof PsiClass && !AnnotationUtil.isAnnotated((PsiModifierListOwner)resolved, CommonClassNames.JAVA_LANG_ANNOTATION_REPEATABLE, false, true);
+ }
+
@Override
public void updateUI(final Object p, @NotNull final ParameterInfoUIContext context) {
if (p instanceof CandidateInfo) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java
index ccec3c3cab07..37fb882e5e66 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java
@@ -187,14 +187,14 @@ public final class FieldFromParameterUtils {
modifierList.setModifierProperty(PsiModifier.FINAL, isFinal);
final NullableNotNullManager manager = NullableNotNullManager.getInstance(project);
- final String nullable = manager.getNullable(parameter);
- if (nullable != null) {
- modifierList.addAfter(factory.createAnnotationFromText("@" + nullable, field), null);
+ final PsiAnnotation nullable = manager.getNullableAnnotation(parameter, false);
+ if (nullable != null && !manager.isContainerAnnotation(nullable)) {
+ modifierList.addAfter(factory.createAnnotationFromText("@" + nullable.getQualifiedName(), field), null);
}
else if (isFinal) {
- final String notNull = manager.getNotNull(parameter);
- if (notNull != null) {
- modifierList.addAfter(factory.createAnnotationFromText("@" + notNull, field), null);
+ final PsiAnnotation notNull = manager.getNotNullAnnotation(parameter, false);
+ if (notNull != null && !manager.isContainerAnnotation(notNull)) {
+ modifierList.addAfter(factory.createAnnotationFromText("@" + notNull.getQualifiedName(), field), null);
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastExpressionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastExpressionPostfixTemplate.java
index 952987a72c19..14059174cc16 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastExpressionPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastExpressionPostfixTemplate.java
@@ -20,13 +20,17 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
-public class CastExpressionPostfixTemplate extends JavaPostfixTemplateWithChooser {
+import static com.intellij.codeInsight.template.postfix.templates.PostfixTemplatesUtils.selectorWithChooser;
+import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_NON_VOID;
+import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO;
+
+public class CastExpressionPostfixTemplate extends PostfixTemplateWithExpressionSelector {
public CastExpressionPostfixTemplate() {
- super("cast", "((SomeType) expr)");
+ super("cast", "((SomeType) expr)", JAVA_PSI_INFO, selectorWithChooser(IS_NON_VOID));
}
@Override
- protected void doIt(@NotNull final Editor editor, @NotNull final PsiElement expression) {
+ protected void expandForChooseExpression(@NotNull PsiElement expression, @NotNull Editor editor) {
PostfixTemplatesUtils.surround(new JavaWithCastSurrounder(), editor, expression);
}
} \ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceFieldPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceFieldPostfixTemplate.java
index 40da7fd94b88..2bac79d890bd 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceFieldPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceFieldPostfixTemplate.java
@@ -23,13 +23,17 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.introduceField.IntroduceFieldHandler;
import org.jetbrains.annotations.NotNull;
-public class IntroduceFieldPostfixTemplate extends JavaPostfixTemplateWithChooser {
+import static com.intellij.codeInsight.template.postfix.templates.PostfixTemplatesUtils.selectorWithChooser;
+import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_NON_VOID;
+import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO;
+
+public class IntroduceFieldPostfixTemplate extends PostfixTemplateWithExpressionSelector {
public IntroduceFieldPostfixTemplate() {
- super("field", "myField = expr");
+ super("field", "myField = expr", JAVA_PSI_INFO, selectorWithChooser(IS_NON_VOID));
}
@Override
- protected void doIt(@NotNull Editor editor, @NotNull PsiElement expression) {
+ protected void expandForChooseExpression(@NotNull PsiElement expression, @NotNull Editor editor) {
IntroduceFieldHandler handler =
ApplicationManager.getApplication().isUnitTestMode() ? getMockHandler(expression) : new IntroduceFieldHandler();
handler.invoke(expression.getProject(), new PsiElement[]{expression}, null);
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceVariablePostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceVariablePostfixTemplate.java
index 57c03f9501fa..be2dc23850e7 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceVariablePostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceVariablePostfixTemplate.java
@@ -28,14 +28,18 @@ import com.intellij.refactoring.introduceVariable.IntroduceVariableSettings;
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
import org.jetbrains.annotations.NotNull;
+import static com.intellij.codeInsight.template.postfix.templates.PostfixTemplatesUtils.selectorWithChooser;
+import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_NON_VOID;
+import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO;
+
// todo: support for int[].var (parses as .class access!)
-public class IntroduceVariablePostfixTemplate extends JavaPostfixTemplateWithChooser {
+public class IntroduceVariablePostfixTemplate extends PostfixTemplateWithExpressionSelector {
public IntroduceVariablePostfixTemplate() {
- super("var", "T name = expr");
+ super("var", "T name = expr", JAVA_PSI_INFO, selectorWithChooser(IS_NON_VOID));
}
@Override
- protected void doIt(@NotNull Editor editor, @NotNull PsiElement expression) {
+ protected void expandForChooseExpression(@NotNull PsiElement expression, @NotNull Editor editor) {
// for advanced stuff use ((PsiJavaCodeReferenceElement)expression).advancedResolve(true).getElement();
IntroduceVariableHandler handler =
ApplicationManager.getApplication().isUnitTestMode() ? getMockHandler() : new IntroduceVariableHandler();
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java
index 148f4bb187db..629d4dd02115 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java
@@ -144,6 +144,6 @@ public class JavaPostfixTemplateProvider implements PostfixTemplateProvider {
}
private static boolean isSemicolonNeeded(@NotNull PsiFile file, @NotNull Editor editor) {
- return JavaCompletionContributor.semicolonNeeded(editor, file, CompletionInitializationContext.calcStartOffset(editor));
+ return JavaCompletionContributor.semicolonNeeded(editor, file, CompletionInitializationContext.calcStartOffset(editor.getCaretModel().getCurrentCaret()));
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateWithChooser.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateWithChooser.java
deleted file mode 100644
index 72de706f4858..000000000000
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateWithChooser.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.codeInsight.template.postfix.templates;
-
-
-import com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils;
-import com.intellij.openapi.util.Condition;
-import com.intellij.psi.PsiElement;
-import org.jetbrains.annotations.NotNull;
-
-import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO;
-
-public abstract class JavaPostfixTemplateWithChooser extends ExpressionPostfixTemplateWithChooser {
-
-
- protected JavaPostfixTemplateWithChooser(@NotNull String name, @NotNull String example) {
- super(name, example, JAVA_PSI_INFO);
- }
-
- protected JavaPostfixTemplateWithChooser(@NotNull String name, @NotNull String key, @NotNull String example) {
- super(name, key, example, JAVA_PSI_INFO);
- }
-
- @NotNull
- @Override
- protected Condition<PsiElement> getTypeCondition() {
- return JavaPostfixTemplatesUtils.IS_NON_VOID;
- }
-}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java
index ac6f22c5092f..6160433cefe3 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java
@@ -15,26 +15,16 @@
*/
package com.intellij.codeInsight.template.postfix.templates;
-import com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils;
-import com.intellij.openapi.util.Condition;
-import com.intellij.psi.PsiElement;
-import org.jetbrains.annotations.NotNull;
-
+import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_BOOLEAN;
import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO;
public class NotExpressionPostfixTemplate extends NotPostfixTemplate {
public NotExpressionPostfixTemplate() {
- super(JAVA_PSI_INFO);
+ super(JAVA_PSI_INFO, IS_BOOLEAN);
}
public NotExpressionPostfixTemplate(String alias) {
- super(alias, alias, "!expr", JAVA_PSI_INFO);
- }
-
- @NotNull
- @Override
- protected Condition<PsiElement> getTypeCondition() {
- return JavaPostfixTemplatesUtils.IS_BOOLEAN;
+ super(alias, alias, "!expr", JAVA_PSI_INFO, IS_BOOLEAN);
}
} \ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedExpressionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedExpressionPostfixTemplate.java
index 68b5c48fcd15..46c0c30b24f5 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedExpressionPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedExpressionPostfixTemplate.java
@@ -15,21 +15,11 @@
*/
package com.intellij.codeInsight.template.postfix.templates;
-import com.intellij.openapi.util.Condition;
-import com.intellij.psi.PsiElement;
-import org.jetbrains.annotations.NotNull;
-
import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_NON_VOID;
import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO;
public class ParenthesizedExpressionPostfixTemplate extends ParenthesizedPostfixTemplate {
public ParenthesizedExpressionPostfixTemplate() {
- super(JAVA_PSI_INFO);
- }
-
- @NotNull
- @Override
- protected Condition<PsiElement> getTypeCondition() {
- return IS_NON_VOID;
+ super(JAVA_PSI_INFO, IS_NON_VOID);
}
} \ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/JavaPostfixTemplatesUtils.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/JavaPostfixTemplatesUtils.java
index e217175cdab9..2142c8fd33da 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/JavaPostfixTemplatesUtils.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/JavaPostfixTemplatesUtils.java
@@ -16,7 +16,7 @@
package com.intellij.codeInsight.template.postfix.util;
import com.intellij.codeInsight.CodeInsightServicesUtil;
-import com.intellij.codeInsight.template.postfix.templates.PostfixTemplatePsiInfoBase;
+import com.intellij.codeInsight.template.postfix.templates.PostfixTemplatePsiInfo;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.*;
@@ -36,7 +36,7 @@ public abstract class JavaPostfixTemplatesUtils {
private JavaPostfixTemplatesUtils() {
}
- public static final PostfixTemplatePsiInfoBase JAVA_PSI_INFO = new PostfixTemplatePsiInfoBase() {
+ public static final PostfixTemplatePsiInfo JAVA_PSI_INFO = new PostfixTemplatePsiInfo() {
@NotNull
@Override
@@ -136,7 +136,11 @@ public abstract class JavaPostfixTemplatesUtils {
@Contract("null -> false")
public static boolean isNotPrimitiveTypeExpression(@Nullable PsiExpression expression) {
- return expression != null && !(expression.getType() instanceof PsiPrimitiveType);
+ if (expression == null) {
+ return false;
+ }
+ PsiType type = expression.getType();
+ return type != null && !(type instanceof PsiPrimitiveType);
}
@Contract("null -> false")
diff --git a/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java b/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java
index aff69ec85da9..b3aed0603150 100644
--- a/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java
+++ b/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java
@@ -194,7 +194,7 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext
final SearchScope searchScope = new GlobalSearchScope(refManager.getProject()) {
@Override
public boolean contains(@NotNull VirtualFile file) {
- return !scope.contains(file) || file.getFileType() != StdFileTypes.JAVA;
+ return scope != null && !scope.contains(file) || file.getFileType() != StdFileTypes.JAVA;
}
@Override
@@ -394,7 +394,7 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext
@Override
public boolean execute(PsiReference reference) {
AnalysisScope scope = context.getRefManager().getScope();
- if (scope.contains(reference.getElement()) && reference.getElement().getLanguage() == StdLanguages.JAVA ||
+ if (scope != null && scope.contains(reference.getElement()) && reference.getElement().getLanguage() == StdLanguages.JAVA ||
PsiTreeUtil.getParentOfType(reference.getElement(), PsiDocComment.class) != null) {
return true;
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java b/java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java
index baab93de8d25..bcfea46a569c 100644
--- a/java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/sameParameterValue/SameParameterValueInspection.java
@@ -76,7 +76,7 @@ public class SameParameterValueInspection extends SameParameterValueInspectionBa
public void applyFix(@NotNull final Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
final PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
- LOG.assertTrue(method != null);
+ if (method == null) return;
PsiParameter parameter = PsiTreeUtil.getParentOfType(element, PsiParameter.class, false);
if (parameter == null) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java b/java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java
index c33d0d68b8cb..bb97f5cd78d5 100644
--- a/java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java
@@ -132,7 +132,7 @@ public class UnusedParametersInspection extends GlobalJavaBatchInspectionTool {
int idx = refParameter.getIndex();
final boolean[] found = {false};
for (int i = 0; i < derived.length && !found[0]; i++) {
- if (!scope.contains(derived[i])) {
+ if (scope == null || !scope.contains(derived[i])) {
final PsiParameter[] parameters = derived[i].getParameterList().getParameters();
if (parameters.length >= idx) continue;
PsiParameter psiParameter = parameters[idx];
diff --git a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java
index 38ee7449994a..51beb4239fc3 100644
--- a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java
@@ -63,7 +63,7 @@ public class FieldCanBeLocalInspection extends FieldCanBeLocalInspectionBase {
@Override
protected PsiElement moveDeclaration(@NotNull final Project project, @NotNull final PsiField variable) {
final Map<PsiCodeBlock, Collection<PsiReference>> refs = new HashMap<PsiCodeBlock, Collection<PsiReference>>();
- groupByCodeBlocks(ReferencesSearch.search(variable).findAll(), refs);
+ if (!groupByCodeBlocks(ReferencesSearch.search(variable).findAll(), refs)) return null;
PsiElement element = null;
for (Collection<PsiReference> psiReferences : refs.values()) {
element = super.moveDeclaration(project, variable, psiReferences, false);
@@ -82,11 +82,14 @@ public class FieldCanBeLocalInspection extends FieldCanBeLocalInspectionBase {
return element;
}
- private static void groupByCodeBlocks(final Collection<PsiReference> allReferences, Map<PsiCodeBlock, Collection<PsiReference>> refs) {
+ private static boolean groupByCodeBlocks(final Collection<PsiReference> allReferences, Map<PsiCodeBlock, Collection<PsiReference>> refs) {
for (PsiReference psiReference : allReferences) {
final PsiElement element = psiReference.getElement();
final PsiCodeBlock block = PsiTreeUtil.getTopmostParentOfType(element, PsiCodeBlock.class);
- LOG.assertTrue(block != null);
+ if (block == null) {
+ return false;
+ }
+
Collection<PsiReference> references = refs.get(block);
if (references == null) {
references = new ArrayList<PsiReference>();
@@ -95,6 +98,7 @@ public class FieldCanBeLocalInspection extends FieldCanBeLocalInspectionBase {
}
references.add(psiReference);
}
+ return true;
}
private static boolean findExistentBlock(Map<PsiCodeBlock, Collection<PsiReference>> refs,
diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java b/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java
index 98f1fbeddfca..73fcc83df646 100644
--- a/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java
+++ b/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java
@@ -28,9 +28,7 @@ import com.intellij.ide.SelectInTarget;
import com.intellij.ide.impl.PackagesPaneSelectInTarget;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.ViewSettings;
-import com.intellij.ide.projectView.impl.nodes.PackageElement;
-import com.intellij.ide.projectView.impl.nodes.PackageUtil;
-import com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode;
+import com.intellij.ide.projectView.impl.nodes.*;
import com.intellij.ide.util.DeleteHandler;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.AbstractTreeNode;
@@ -48,8 +46,8 @@ import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -140,14 +138,30 @@ public final class PackageViewPane extends AbstractProjectViewPSIPane {
@Override
public PsiDirectory[] getSelectedDirectories() {
- final PackageElement packageElement = getSelectedPackageElement();
- if (packageElement != null) {
- final Module module = packageElement.getModule();
- final PsiPackage aPackage = packageElement.getPackage();
- if (module != null && aPackage != null) {
- return aPackage.getDirectories(GlobalSearchScope.moduleScope(module));
+ List<PsiDirectory> directories = ContainerUtil.newArrayList();
+ for (PackageElementNode node : getSelectedNodes(PackageElementNode.class)) {
+ PackageElement packageElement = node.getValue();
+ PsiPackage aPackage = packageElement != null ? packageElement.getPackage() : null;
+ final Module module = packageElement != null ? packageElement.getModule() : null;
+ if (aPackage != null && module != null) {
+ GlobalSearchScope scope = GlobalSearchScope.moduleScope(module);
+ Collections.addAll(directories, aPackage.getDirectories(scope));
+
+ Object parentValue = node.getParent().getValue();
+ PsiPackage parentNodePackage = parentValue instanceof PackageElement ? ((PackageElement)parentValue).getPackage() : null;
+ while (true) {
+ aPackage = aPackage.getParentPackage();
+ if (aPackage == null || aPackage.getQualifiedName().isEmpty() || aPackage.equals(parentNodePackage)) {
+ break;
+ }
+ Collections.addAll(directories, aPackage.getDirectories(scope));
+ }
}
}
+ if (!directories.isEmpty()) {
+ return directories.toArray(new PsiDirectory[directories.size()]);
+ }
+
return super.getSelectedDirectories();
}
diff --git a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java
index b0cbc06d048e..2f5418631dae 100644
--- a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java
+++ b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java
@@ -19,10 +19,14 @@ import com.intellij.navigation.ChooseByNameContributorEx;
import com.intellij.navigation.GotoClassContributor;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiClass;
+import com.intellij.psi.codeStyle.MinusculeMatcher;
+import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.psi.util.ClassUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
@@ -32,6 +36,8 @@ import com.intellij.util.indexing.IdFilter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.regex.Matcher;
+
public class DefaultClassNavigationContributor implements ChooseByNameContributorEx, GotoClassContributor {
@Override
@NotNull
@@ -74,7 +80,7 @@ public class DefaultClassNavigationContributor implements ChooseByNameContributo
@Override
public String getQualifiedNameSeparator() {
- return ".";
+ return "$";
}
@Override
@@ -86,12 +92,28 @@ public class DefaultClassNavigationContributor implements ChooseByNameContributo
public void processElementsWithName(@NotNull String name,
@NotNull final Processor<NavigationItem> processor,
@NotNull final FindSymbolParameters parameters) {
+ String namePattern = StringUtil.getShortName(parameters.getCompletePattern());
+ boolean hasDollar = namePattern.contains("$");
+ if (hasDollar) {
+ Matcher matcher = ChooseByNamePopup.patternToDetectAnonymousClasses.matcher(namePattern);
+ if (matcher.matches()) {
+ namePattern = matcher.group(1);
+ hasDollar = namePattern.contains("$");
+ }
+ }
+ final MinusculeMatcher innerMatcher = hasDollar ? new MinusculeMatcher("*" + namePattern, NameUtil.MatchingCaseSensitivity.NONE) : null;
PsiShortNamesCache.getInstance(parameters.getProject()).processClassesWithName(name, new Processor<PsiClass>() {
final boolean isAnnotation = parameters.getLocalPatternName().startsWith("@");
+
@Override
public boolean process(PsiClass aClass) {
if (aClass.getContainingFile().getVirtualFile() == null || !aClass.isPhysical()) return true;
if (isAnnotation && !aClass.isAnnotationType()) return true;
+ if (innerMatcher != null) {
+ if (aClass.getContainingClass() == null) return true;
+ String jvmQName = ClassUtil.getJVMClassName(aClass);
+ if (jvmQName == null || !innerMatcher.matches(StringUtil.getShortName(jvmQName))) return true;
+ }
return processor.process(aClass);
}
}, parameters.getSearchScope(), parameters.getIdFilter());
diff --git a/java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java b/java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java
index adbacfcd38ce..c825d8318edc 100644
--- a/java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java
+++ b/java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java
@@ -15,16 +15,12 @@
*/
package com.intellij.openapi.roots.impl;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.roots.CompilerProjectExtension;
import com.intellij.openapi.roots.ModuleRootModel;
-import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
-import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -40,26 +36,6 @@ public class ExcludeCompilerOutputPolicy implements DirectoryIndexExcludePolicy
myProject = project;
}
- @Override
- public boolean isExcludeRoot(final VirtualFile file) {
- CompilerProjectExtension compilerProjectExtension = CompilerProjectExtension.getInstance(myProject);
- if (isEqualWithFileOrUrl(file, compilerProjectExtension.getCompilerOutput(), compilerProjectExtension.getCompilerOutputUrl())) return true;
-
- for (Module m : ModuleManager.getInstance(myProject).getModules()) {
- CompilerModuleExtension rm = CompilerModuleExtension.getInstance(m);
- if (isEqualWithFileOrUrl(file, rm.getCompilerOutputPath(), rm.getCompilerOutputUrl())) return true;
- if (isEqualWithFileOrUrl(file, rm.getCompilerOutputPathForTests(), rm.getCompilerOutputUrlForTests())) return true;
- }
- return false;
- }
-
- @Override
- public boolean isExcludeRootForModule(@NotNull final Module module, final VirtualFile excludeRoot) {
- final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
- return Comparing.equal(compilerModuleExtension.getCompilerOutputPath(), excludeRoot) ||
- Comparing.equal(compilerModuleExtension.getCompilerOutputPathForTests(), excludeRoot);
- }
-
@NotNull
@Override
public VirtualFile[] getExcludeRootsForProject() {
@@ -88,14 +64,4 @@ public class ExcludeCompilerOutputPolicy implements DirectoryIndexExcludePolicy
}
return result.isEmpty() ? VirtualFilePointer.EMPTY_ARRAY : result.toArray(new VirtualFilePointer[result.size()]);
}
-
- private static boolean isEqualWithFileOrUrl(VirtualFile file, VirtualFile fileToCompareWith, String url) {
- if (fileToCompareWith != null) {
- if (Comparing.equal(fileToCompareWith, file)) return true;
- }
- else if (url != null) {
- if (FileUtil.pathsEqual(url, file.getUrl())) return true;
- }
- return false;
- }
}
diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java
index 3651fa1afe3a..ff1170b64bef 100644
--- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java
+++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java
@@ -280,6 +280,7 @@ public class JavaArrangementVisitor extends JavaRecursiveElementVisitor {
if (ref instanceof PsiField && containingClassFields.contains(ref)) {
referencedElements.add((PsiField)ref);
}
+ super.visitReferenceExpression(expression);
}
});
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java b/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java
index a8316f8dc0ee..eaa93875ba15 100644
--- a/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java
+++ b/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java
@@ -18,6 +18,7 @@ package com.intellij.psi.impl.search;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.ParserDefinition;
import com.intellij.lexer.Lexer;
+import com.intellij.openapi.editor.impl.EditorHighlighterCache;
import com.intellij.psi.JspPsiUtil;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.tree.StdTokenSets;
@@ -34,7 +35,7 @@ public class JspIndexPatternBuilder implements IndexPatternBuilder {
@Override
public Lexer getIndexingLexer(@NotNull final PsiFile file) {
if (JspPsiUtil.isInJspFile(file)) {
- return LexerEditorHighlighterLexer.getLexerBasedOnLexerHighlighter(file.getText(), file.getVirtualFile(), file.getProject());
+ return EditorHighlighterCache.getLexerBasedOnLexerHighlighter(file.getText(), file.getVirtualFile(), file.getProject());
}
return null;
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FilePathReferenceProvider.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FilePathReferenceProvider.java
index 827a3d128a24..5380043307c7 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FilePathReferenceProvider.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FilePathReferenceProvider.java
@@ -142,9 +142,7 @@ public class FilePathReferenceProvider extends PsiReferenceProvider {
@NotNull
public static Collection<PsiFileSystemItem> getRoots(final Module thisModule, boolean includingClasses) {
if (thisModule == null) return Collections.emptyList();
- Set<Module> modules = new com.intellij.util.containers.HashSet<Module>();
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(thisModule);
- ModuleUtilCore.getDependencies(thisModule, modules);
List<PsiFileSystemItem> result = new ArrayList<PsiFileSystemItem>();
final PsiManager psiManager = PsiManager.getInstance(thisModule.getProject());
if (includingClasses) {
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/MethodPropertyReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/MethodPropertyReference.java
index f7dc89ce5b80..307d608ddbd8 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/MethodPropertyReference.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/MethodPropertyReference.java
@@ -16,7 +16,6 @@
package com.intellij.psi.impl.source.resolve.reference.impl.providers;
import com.intellij.psi.*;
-import com.intellij.psi.jsp.JspImplicitVariable;
import com.intellij.psi.jsp.JspSpiUtil;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.xml.XmlAttribute;
@@ -62,8 +61,8 @@ public class MethodPropertyReference extends BasicAttributeValueReference {
}
} else if (psiElement instanceof PsiClass) {
return (PsiClass)psiElement;
- } else if (psiElement instanceof JspImplicitVariable) {
- final PsiType type=((JspImplicitVariable)psiElement).getType();
+ } else if (psiElement instanceof PsiVariable) {
+ final PsiType type=((PsiVariable)psiElement).getType();
if (type instanceof PsiClassType) {
return ((PsiClassType)type).resolve();
}
diff --git a/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java b/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
index 7bca3c07b4c0..80201559ef34 100644
--- a/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
@@ -86,20 +86,23 @@ class AnonymousToInnerDialog extends DialogWrapper{
final String[] names;
String name = myAnonClass.getBaseClassReference().getReferenceName();
PsiType[] typeParameters = myAnonClass.getBaseClassReference().getTypeParameters();
- if (typeParameters.length > 0) {
- names = new String[]{StringUtil.join(typeParameters, new Function<PsiType, String>() {
- public String fun(PsiType psiType) {
- PsiType type = psiType;
- if (psiType instanceof PsiClassType) {
- type = TypeConversionUtil.erasure(psiType);
- }
- if (type == null || type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) return "";
- if (type instanceof PsiArrayType) {
- type = type.getDeepComponentType();
- }
- return StringUtil.getShortName(type.getPresentableText());
+
+ final String typeParamsList = StringUtil.join(typeParameters, new Function<PsiType, String>() {
+ public String fun(PsiType psiType) {
+ PsiType type = psiType;
+ if (psiType instanceof PsiClassType) {
+ type = TypeConversionUtil.erasure(psiType);
}
- }, "") + name, "My" + name};
+ if (type == null || type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) return "";
+ if (type instanceof PsiArrayType) {
+ type = type.getDeepComponentType();
+ }
+ return StringUtil.getShortName(type.getPresentableText());
+ }
+ }, "") + name;
+
+ if (!typeParamsList.equals(name)) {
+ names = new String[]{typeParamsList, "My" + name};
} else {
names = new String[]{"My" + name};
}
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
index 75544f9d8ab9..ce52274140bb 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
+import com.intellij.codeInsight.daemon.impl.quickfix.AnonymousTargetClassPreselectionUtil;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
import com.intellij.codeInsight.navigation.NavigationUtil;
@@ -1133,6 +1134,7 @@ public class ExtractMethodProcessor implements MatchProvider {
final PsiElementProcessor<PsiClass> processor = new PsiElementProcessor<PsiClass>() {
@Override
public boolean execute(@NotNull PsiClass selectedClass) {
+ AnonymousTargetClassPreselectionUtil.rememberSelection(selectedClass, myTargetClass);
final List<PsiVariable> array = classes.get(selectedClass);
myNeedChangeContext = myTargetClass != selectedClass;
myTargetClass = selectedClass;
@@ -1184,7 +1186,9 @@ public class ExtractMethodProcessor implements MatchProvider {
if (classes.size() > 1) {
final PsiClass[] psiClasses = classes.keySet().toArray(new PsiClass[classes.size()]);
- NavigationUtil.getPsiElementPopup(psiClasses, new PsiClassListCellRenderer(), "Choose Destination Class", processor).showInBestPositionFor(myEditor);
+ final PsiClass preselection = AnonymousTargetClassPreselectionUtil.getPreselection(classes.keySet(), psiClasses[0]);
+ NavigationUtil.getPsiElementPopup(psiClasses, new PsiClassListCellRenderer(), "Choose Destination Class", processor, preselection)
+ .showInBestPositionFor(myEditor);
return true;
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java
index a751acea42df..75473959ddcc 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java
@@ -27,6 +27,7 @@ package com.intellij.refactoring.introduceField;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.codeInsight.TestFrameworks;
+import com.intellij.codeInsight.daemon.impl.quickfix.AnonymousTargetClassPreselectionUtil;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.navigation.NavigationUtil;
@@ -129,18 +130,13 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
return !convertExpressionToField(selectedExpr, editor, file, project, tempType);
}
else {
- PsiClass selection = null;
- for (PsiClass psiClass : classes) {
- if (!(psiClass instanceof PsiAnonymousClass)) {
- selection = psiClass;
- break;
- }
- }
+ PsiClass selection = AnonymousTargetClassPreselectionUtil.getPreselection(classes, myParentClass);
NavigationUtil.getPsiElementPopup(classes.toArray(new PsiClass[classes.size()]), new PsiClassListCellRenderer(),
"Choose class to introduce " + (myIsConstant ? "constant" : "field"),
new PsiElementProcessor<PsiClass>() {
@Override
public boolean execute(@NotNull PsiClass aClass) {
+ AnonymousTargetClassPreselectionUtil.rememberSelection(aClass, myParentClass);
myParentClass = aClass;
convertExpressionToField(selectedExpr, editor, file, project, tempType);
return false;
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java
index 5b5c39fb10a8..0b31eedf8be0 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java
@@ -18,6 +18,7 @@ package com.intellij.refactoring.introduceField;
import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.codeInsight.CodeInsightUtil;
import com.intellij.codeInsight.TestFrameworks;
+import com.intellij.codeInsight.daemon.impl.quickfix.AnonymousTargetClassPreselectionUtil;
import com.intellij.codeInsight.navigation.NavigationUtil;
import com.intellij.ide.util.PsiClassListCellRenderer;
import com.intellij.openapi.application.ApplicationManager;
@@ -66,7 +67,7 @@ public abstract class LocalToFieldHandler {
public boolean convertLocalToField(final PsiLocalVariable local, final Editor editor) {
boolean tempIsStatic = myIsConstant;
PsiElement parent = local.getParent();
- List<PsiClass> classes = new ArrayList<PsiClass>();
+ final List<PsiClass> classes = new ArrayList<PsiClass>();
while (parent != null && parent.getContainingFile() != null) {
if (parent instanceof PsiClass && !(myIsConstant && parent instanceof PsiAnonymousClass)) {
classes.add((PsiClass)parent);
@@ -90,13 +91,16 @@ public abstract class LocalToFieldHandler {
if (convertLocalToField(local, classes.get(getChosenClassIndex(classes)), editor, tempIsStatic)) return false;
} else {
final boolean isStatic = tempIsStatic;
+ final PsiClass firstClass = classes.get(0);
+ final PsiClass preselection = AnonymousTargetClassPreselectionUtil.getPreselection(classes, firstClass);
NavigationUtil.getPsiElementPopup(classes.toArray(new PsiClass[classes.size()]), new PsiClassListCellRenderer(), "Choose class to introduce " + (myIsConstant ? "constant" : "field"), new PsiElementProcessor<PsiClass>() {
@Override
public boolean execute(@NotNull PsiClass aClass) {
+ AnonymousTargetClassPreselectionUtil.rememberSelection(aClass, aClass);
convertLocalToField(local, aClass, editor, isStatic);
return false;
}
- }).showInBestPositionFor(editor);
+ }, preselection).showInBestPositionFor(editor);
}
return true;
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaMethodProcessor.java
index c410d763dac1..f09da834c348 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaMethodProcessor.java
@@ -210,10 +210,16 @@ public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor {
if (element instanceof PsiReferenceExpression) {
if (((PsiReferenceExpression)element).resolve() == methodToRename) {
final PsiElement parent = element.getParent();
- LOG.assertTrue(parent instanceof PsiMethodCallExpression, parent.getText());
- final PsiMethodCallExpression copy = (PsiMethodCallExpression)JavaPsiFacade.getElementFactory(element.getProject())
- .createExpressionFromText(parent.getText(), element);
- final PsiReferenceExpression expression = (PsiReferenceExpression)processRef(copy.getMethodExpression(), newName);
+ final PsiReferenceExpression copyRef;
+ if (parent instanceof PsiMethodCallExpression) {
+ final PsiMethodCallExpression copy = (PsiMethodCallExpression)JavaPsiFacade.getElementFactory(element.getProject())
+ .createExpressionFromText(parent.getText(), element);
+ copyRef = copy.getMethodExpression();
+ } else {
+ LOG.assertTrue(element instanceof PsiMethodReferenceExpression, element.getText());
+ copyRef = (PsiReferenceExpression)element.copy();
+ }
+ final PsiReferenceExpression expression = (PsiReferenceExpression)processRef(copyRef, newName);
if (expression == null) continue;
final JavaResolveResult resolveResult = expression.advancedResolve(true);
final PsiMember resolveResultElement = (PsiMember)resolveResult.getElement();
diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
index f2ac34e8aed0..ca01331d3e94 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
@@ -617,7 +617,7 @@ public class RefactoringUtil {
Project project = expr.getProject();
String[] suggestedNames =
JavaCodeStyleManager.getInstance(project).suggestVariableName(VariableKind.LOCAL_VARIABLE, null, expr, null).names;
- final String prefix = suggestedNames[0];
+ final String prefix = suggestedNames.length > 0 ? suggestedNames[0] : "var";
final String id = JavaCodeStyleManager.getInstance(project).suggestUniqueVariableName(prefix, context, true);
PsiElementFactory factory = JavaPsiFacade.getInstance(expr.getProject()).getElementFactory();
diff --git a/java/java-impl/src/com/intellij/testIntegration/createTest/MissedTestsDialog.java b/java/java-impl/src/com/intellij/testIntegration/createTest/MissedTestsDialog.java
index b34d28e3f6f4..ee8bcf0d1c1c 100644
--- a/java/java-impl/src/com/intellij/testIntegration/createTest/MissedTestsDialog.java
+++ b/java/java-impl/src/com/intellij/testIntegration/createTest/MissedTestsDialog.java
@@ -20,19 +20,15 @@ import com.intellij.codeInsight.template.Template;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.JavaPsiFacade;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiMember;
-import com.intellij.psi.PsiMethod;
-import com.intellij.refactoring.ui.MemberSelectionPanel;
+import com.intellij.psi.*;
import com.intellij.refactoring.ui.MemberSelectionTable;
import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.testIntegration.TestFramework;
import com.intellij.testIntegration.TestIntegrationUtils;
import com.intellij.ui.ScrollPaneFactory;
-import com.intellij.ui.SeparatorFactory;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.util.Function;
+import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
@@ -40,8 +36,10 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.*;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
public class MissedTestsDialog extends DialogWrapper {
private final PsiClass mySourceClass;
@@ -85,9 +83,7 @@ public class MissedTestsDialog extends DialogWrapper {
private void disableMethodsWithTests(List<MemberInfo> info) {
final Set<String> existingNames = new HashSet<String>();
- final Template template = TestIntegrationUtils
- .createTestMethodTemplate(TestIntegrationUtils.MethodKind.TEST, myDescriptor, myTestClass, null, true, existingNames);
- final String prefix = JavaPsiFacade.getElementFactory(myTestClass.getProject()).createMethodFromText(template.getTemplateText(), myTestClass).getName();
+ final String prefix = getTestPrefix(existingNames);
existingNames.addAll(ContainerUtil.map(myTestClass.getMethods(), new Function<PsiMethod, String>() {
@Override
@@ -103,6 +99,16 @@ public class MissedTestsDialog extends DialogWrapper {
}
}
+ private String getTestPrefix(Set<String> existingNames) {
+ final Template template = TestIntegrationUtils.createTestMethodTemplate(TestIntegrationUtils.MethodKind.TEST, myDescriptor, myTestClass, null, true, existingNames);
+ try {
+ return JavaPsiFacade.getElementFactory(myTestClass.getProject()).createMethodFromText(template.getTemplateText(), myTestClass).getName();
+ }
+ catch (IncorrectOperationException e) {
+ return "";
+ }
+ }
+
private void updateMethodsTable() {
List<MemberInfo> infos = TestIntegrationUtils.extractClassMethods(mySourceClass, myIncludeInheritedCb.isSelected());
diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/JavaUsageTypeProvider.java b/java/java-impl/src/com/intellij/usages/impl/rules/JavaUsageTypeProvider.java
index 445a8aab14a2..93b9737bdfe3 100644
--- a/java/java-impl/src/com/intellij/usages/impl/rules/JavaUsageTypeProvider.java
+++ b/java/java-impl/src/com/intellij/usages/impl/rules/JavaUsageTypeProvider.java
@@ -70,7 +70,8 @@ public class JavaUsageTypeProvider implements UsageTypeProviderEx {
return UsageType.RECURSION;
}
if (qualifier != null && !(qualifier instanceof PsiThisExpression) && calledMethod != null) {
- if (haveCommonSuperMethod(containerMethod, calledMethod)) {
+ if (Comparing.equal(containerMethod.getName(), calledMethod.getName()) &&
+ haveCommonSuperMethod(containerMethod, calledMethod)) {
boolean parametersDelegated = parametersDelegated(containerMethod, callExpression);
if (qualifier instanceof PsiSuperExpression) {
diff --git a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.java
new file mode 100644
index 000000000000..c7d9e303aae3
--- /dev/null
+++ b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationTargetUtil.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 com.intellij.codeInsight;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author peter
+ */
+public class AnnotationTargetUtil {
+ public static final Set<PsiAnnotation.TargetType> DEFAULT_TARGETS = Collections.unmodifiableSet(ContainerUtil.newHashSet(
+ PsiAnnotation.TargetType.PACKAGE, PsiAnnotation.TargetType.TYPE, PsiAnnotation.TargetType.ANNOTATION_TYPE,
+ PsiAnnotation.TargetType.FIELD, PsiAnnotation.TargetType.METHOD, PsiAnnotation.TargetType.CONSTRUCTOR,
+ PsiAnnotation.TargetType.PARAMETER, PsiAnnotation.TargetType.LOCAL_VARIABLE));
+ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.AnnotationUtil");
+ private static final PsiAnnotation.TargetType[] PACKAGE_TARGETS = {PsiAnnotation.TargetType.PACKAGE};
+ private static final PsiAnnotation.TargetType[] TYPE_USE_TARGETS = {PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] ANNOTATION_TARGETS = {PsiAnnotation.TargetType.ANNOTATION_TYPE, PsiAnnotation.TargetType.TYPE, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] TYPE_TARGETS = {PsiAnnotation.TargetType.TYPE, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] TYPE_PARAMETER_TARGETS = {
+ PsiAnnotation.TargetType.TYPE_PARAMETER, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] CONSTRUCTOR_TARGETS = {PsiAnnotation.TargetType.CONSTRUCTOR, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] METHOD_TARGETS = {PsiAnnotation.TargetType.METHOD, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] FIELD_TARGETS = {PsiAnnotation.TargetType.FIELD, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] PARAMETER_TARGETS = {PsiAnnotation.TargetType.PARAMETER, PsiAnnotation.TargetType.TYPE_USE};
+ private static final PsiAnnotation.TargetType[] LOCAL_VARIABLE_TARGETS ={
+ PsiAnnotation.TargetType.LOCAL_VARIABLE, PsiAnnotation.TargetType.TYPE_USE};
+
+ @NotNull
+ public static PsiAnnotation.TargetType[] getTargetsForLocation(@Nullable PsiAnnotationOwner owner) {
+ if (owner == null) {
+ return PsiAnnotation.TargetType.EMPTY_ARRAY;
+ }
+
+ if (owner instanceof PsiType || owner instanceof PsiTypeElement) {
+ return TYPE_USE_TARGETS;
+ }
+
+ if (owner instanceof PsiTypeParameter) {
+ return TYPE_PARAMETER_TARGETS;
+ }
+
+ if (owner instanceof PsiModifierList) {
+ PsiElement element = ((PsiModifierList)owner).getParent();
+ if (element instanceof PsiPackageStatement) {
+ return PACKAGE_TARGETS;
+ }
+ if (element instanceof PsiClass) {
+ if (((PsiClass)element).isAnnotationType()) {
+ return ANNOTATION_TARGETS;
+ }
+ else {
+ return TYPE_TARGETS;
+ }
+ }
+ if (element instanceof PsiMethod) {
+ if (((PsiMethod)element).isConstructor()) {
+ return CONSTRUCTOR_TARGETS;
+ }
+ else {
+ return METHOD_TARGETS;
+ }
+ }
+ if (element instanceof PsiField) {
+ return FIELD_TARGETS;
+ }
+ if (element instanceof PsiParameter) {
+ return PARAMETER_TARGETS;
+ }
+ if (element instanceof PsiLocalVariable) {
+ return LOCAL_VARIABLE_TARGETS;
+ }
+ }
+
+ return PsiAnnotation.TargetType.EMPTY_ARRAY;
+ }
+
+ @Nullable
+ public static Set<PsiAnnotation.TargetType> extractRequiredAnnotationTargets(@Nullable PsiAnnotationMemberValue value) {
+ if (value instanceof PsiReference) {
+ PsiAnnotation.TargetType targetType = translateTargetRef((PsiReference)value);
+ if (targetType != null) {
+ return Collections.singleton(targetType);
+ }
+ }
+ else if (value instanceof PsiArrayInitializerMemberValue) {
+ Set <PsiAnnotation.TargetType> targets = ContainerUtil.newHashSet();
+ for (PsiAnnotationMemberValue initializer : ((PsiArrayInitializerMemberValue)value).getInitializers()) {
+ if (initializer instanceof PsiReference) {
+ PsiAnnotation.TargetType targetType = translateTargetRef((PsiReference)initializer);
+ if (targetType != null) {
+ targets.add(targetType);
+ }
+ }
+ }
+ return targets;
+ }
+
+ return null;
+ }
+
+ @Nullable
+ private static PsiAnnotation.TargetType translateTargetRef(@NotNull PsiReference reference) {
+ PsiElement field = reference.resolve();
+ if (field instanceof PsiEnumConstant) {
+ String name = ((PsiEnumConstant)field).getName();
+ try {
+ return PsiAnnotation.TargetType.valueOf(name);
+ }
+ catch (IllegalArgumentException e) {
+ LOG.warn("Unknown target: " + name);
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
index c2c79a9d9d8a..25034e9ab7ba 100644
--- a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
+++ b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
@@ -379,14 +379,14 @@ public class AnnotationUtil {
@NotNull
public static PsiAnnotation[] getAllAnnotations(@NotNull PsiModifierListOwner owner,
boolean inHierarchy,
- Set<PsiModifierListOwner> visited) {
+ @Nullable Set<PsiModifierListOwner> visited) {
return getAllAnnotations(owner, inHierarchy, visited, true);
}
@NotNull
public static PsiAnnotation[] getAllAnnotations(@NotNull PsiModifierListOwner owner,
boolean inHierarchy,
- Set<PsiModifierListOwner> visited, boolean withInferred) {
+ @Nullable Set<PsiModifierListOwner> visited, boolean withInferred) {
final PsiModifierList list = owner.getModifierList();
PsiAnnotation[] annotations = PsiAnnotation.EMPTY_ARRAY;
if (list != null) {
diff --git a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java
index 21e014e4aca3..2210e02a080a 100644
--- a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java
+++ b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java
@@ -44,10 +44,13 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
public final JDOMExternalizableStringList myNullables = new JDOMExternalizableStringList();
public final JDOMExternalizableStringList myNotNulls = new JDOMExternalizableStringList();
- public static final String[] DEFAULT_NULLABLES = {AnnotationUtil.NULLABLE, "javax.annotation.Nullable",
+ private static final String JAVAX_ANNOTATION_NULLABLE = "javax.annotation.Nullable";
+ private static final String JAVAX_ANNOTATION_NONNULL = "javax.annotation.Nonnull";
+
+ public static final String[] DEFAULT_NULLABLES = {AnnotationUtil.NULLABLE, JAVAX_ANNOTATION_NULLABLE,
"edu.umd.cs.findbugs.annotations.Nullable", "android.support.annotation.Nullable"
};
- public static final String[] DEFAULT_NOT_NULLS = {AnnotationUtil.NOT_NULL, "javax.annotation.Nonnull",
+ public static final String[] DEFAULT_NOT_NULLS = {AnnotationUtil.NOT_NULL, JAVAX_ANNOTATION_NONNULL,
"edu.umd.cs.findbugs.annotations.NonNull", "android.support.annotation.NonNull"
};
@@ -103,6 +106,11 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
return findNullabilityAnnotation(owner, checkBases, true);
}
+ public boolean isContainerAnnotation(@NotNull PsiAnnotation anno) {
+ PsiAnnotation.TargetType[] acceptAnyTarget = PsiAnnotation.TargetType.values();
+ return isNullabilityDefault(anno, true, acceptAnyTarget) || isNullabilityDefault(anno, false, acceptAnyTarget);
+ }
+
public void setDefaultNullable(@NotNull String defaultNullable) {
LOG.assertTrue(getNullables().contains(defaultNullable));
myDefaultNullable = defaultNullable;
@@ -138,15 +146,20 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
return annotation;
}
- if (owner instanceof PsiParameter && !TypeConversionUtil.isPrimitiveAndNotNull(((PsiParameter)owner).getType())) {
- // even if javax.annotation.Nullable is not configured, it should still take precedence over ByDefault annotations
- if (AnnotationUtil.isAnnotated(owner, nullable ? Arrays.asList(DEFAULT_NOT_NULLS) : Arrays.asList(DEFAULT_NULLABLES), checkBases, false)) {
- return null;
- }
- return findContainerAnnotation(owner, nullable
- ? "javax.annotation.ParametersAreNullableByDefault"
- : "javax.annotation.ParametersAreNonnullByDefault");
+ PsiType type = getOwnerType(owner);
+ if (type == null || TypeConversionUtil.isPrimitiveAndNotNull(type)) return null;
+
+ // even if javax.annotation.Nullable is not configured, it should still take precedence over ByDefault annotations
+ if (AnnotationUtil.isAnnotated(owner, nullable ? Arrays.asList(DEFAULT_NOT_NULLS) : Arrays.asList(DEFAULT_NULLABLES), checkBases, false)) {
+ return null;
}
+ return findNullabilityDefaultInHierarchy(owner, nullable);
+ }
+
+ @Nullable
+ private static PsiType getOwnerType(PsiModifierListOwner owner) {
+ if (owner instanceof PsiVariable) return ((PsiVariable)owner).getType();
+ if (owner instanceof PsiMethod) return ((PsiMethod)owner).getReturnType();
return null;
}
@@ -159,11 +172,13 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
}
@Nullable
- private static PsiAnnotation findContainerAnnotation(PsiModifierListOwner owner, String annotationFQN) {
+ private static PsiAnnotation findNullabilityDefaultInHierarchy(PsiModifierListOwner owner, boolean nullable) {
+ PsiAnnotation.TargetType[] placeTargetTypes = AnnotationTargetUtil.getTargetsForLocation(owner.getModifierList());
+
PsiElement element = owner.getParent();
while (element != null) {
if (element instanceof PsiModifierListOwner) {
- PsiAnnotation annotation = AnnotationUtil.findAnnotation((PsiModifierListOwner)element, annotationFQN);
+ PsiAnnotation annotation = getNullabilityDefault((PsiModifierListOwner)element, nullable, placeTargetTypes);
if (annotation != null) {
return annotation;
}
@@ -172,7 +187,7 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
if (element instanceof PsiClassOwner) {
String packageName = ((PsiClassOwner)element).getPackageName();
PsiPackage psiPackage = JavaPsiFacade.getInstance(element.getProject()).findPackage(packageName);
- return AnnotationUtil.findAnnotation(psiPackage, annotationFQN);
+ return psiPackage == null ? null : getNullabilityDefault(psiPackage, nullable, placeTargetTypes);
}
element = element.getContext();
@@ -180,6 +195,37 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
return null;
}
+ private static PsiAnnotation getNullabilityDefault(@NotNull PsiModifierListOwner container, boolean nullable, PsiAnnotation.TargetType[] placeTargetTypes) {
+ PsiModifierList modifierList = container.getModifierList();
+ if (modifierList == null) return null;
+ for (PsiAnnotation annotation : modifierList.getAnnotations()) {
+ if (isNullabilityDefault(annotation, nullable, placeTargetTypes)) {
+ return annotation;
+ }
+ }
+ return null;
+ }
+
+ private static boolean isNullabilityDefault(@NotNull PsiAnnotation annotation, boolean nullable, PsiAnnotation.TargetType[] placeTargetTypes) {
+ PsiJavaCodeReferenceElement element = annotation.getNameReferenceElement();
+ PsiElement declaration = element == null ? null : element.resolve();
+ if (!(declaration instanceof PsiClass)) return false;
+
+ if (!AnnotationUtil.isAnnotated((PsiClass)declaration,
+ nullable ? JAVAX_ANNOTATION_NULLABLE : JAVAX_ANNOTATION_NONNULL,
+ false,
+ true)) {
+ return false;
+ }
+
+ PsiAnnotation tqDefault = AnnotationUtil.findAnnotation((PsiClass)declaration, true, "javax.annotation.meta.TypeQualifierDefault");
+ if (tqDefault == null) return false;
+
+ Set<PsiAnnotation.TargetType> required = AnnotationTargetUtil.extractRequiredAnnotationTargets(tqDefault.findAttributeValue(null));
+ if (required == null) return false;
+ return required.isEmpty() || ContainerUtil.intersects(required, Arrays.asList(placeTargetTypes));
+ }
+
public List<String> getNullables() {
return myNullables;
}
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 7cabc118fc6c..52888f123215 100644
--- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
@@ -476,6 +476,9 @@ public class GenericsUtil {
PsiType substituted = resolveResult.getSubstitutor().substitute(typeParam);
if (substituted instanceof PsiWildcardType) {
substituted = ((PsiWildcardType)substituted).getBound();
+ if (substituted instanceof PsiCapturedWildcardType) {
+ substituted = ((PsiCapturedWildcardType)substituted).getWildcard().getBound();
+ }
if (substituted == null) substituted = TypeConversionUtil.typeParameterErasure(typeParam);
}
map.put(typeParam, substituted);
diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
index e7506ebd92fd..f43358007eab 100644
--- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
+++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
@@ -180,7 +180,7 @@ public class MethodCandidateInfo extends CandidateInfo{
@NotNull
public PsiSubstitutor getSubstitutor(boolean includeReturnConstraint) {
PsiSubstitutor substitutor = myCalcedSubstitutor;
- if (substitutor == null || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
+ if (substitutor == null || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) || isOverloadCheck()) {
PsiSubstitutor incompleteSubstitutor = super.getSubstitutor();
PsiMethod method = getElement();
if (myTypeArguments == null) {
@@ -189,7 +189,7 @@ public class MethodCandidateInfo extends CandidateInfo{
final PsiSubstitutor inferredSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint);
if (!stackStamp.mayCacheNow() ||
- !ourOverloadGuard.currentStack().isEmpty() ||
+ isOverloadCheck() ||
!includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) ||
getMarkerList() != null && PsiResolveHelper.ourGraphGuard.currentStack().contains(getMarkerList().getParent())) {
return inferredSubstitutor;
@@ -209,6 +209,10 @@ public class MethodCandidateInfo extends CandidateInfo{
return substitutor;
}
+ public static boolean isOverloadCheck() {
+ return !ourOverloadGuard.currentStack().isEmpty();
+ }
+
public boolean isTypeArgumentsApplicable() {
return isTypeArgumentsApplicable(false);
diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java
index 622714c6dd61..22591801e32e 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java
@@ -114,7 +114,7 @@ public class MethodSignatureUtil {
}
public static boolean areSignaturesEqual(@NotNull PsiMethod method1, @NotNull PsiMethod method2) {
- return method1.getSignature(PsiSubstitutor.EMPTY).equals(method2.getSignature(PsiSubstitutor.EMPTY));
+ return areSignaturesEqual(method1.getSignature(PsiSubstitutor.EMPTY), method2.getSignature(PsiSubstitutor.EMPTY));
}
public static boolean areSignaturesEqual(@NotNull MethodSignature method1, @NotNull MethodSignature method2) {
@@ -172,10 +172,10 @@ public class MethodSignatureUtil {
public static boolean isSuperMethod(@NotNull PsiMethod superMethodCandidate, @NotNull PsiMethod derivedMethod) {
PsiClass superClassCandidate = superMethodCandidate.getContainingClass();
PsiClass derivedClass = derivedMethod.getContainingClass();
- if (derivedClass == null || superClassCandidate == null) return false;
- if (!derivedClass.isInheritor(superClassCandidate, true)) return false;
- final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClassCandidate, derivedClass,
- PsiSubstitutor.EMPTY);
+ if (derivedClass == null || superClassCandidate == null || derivedClass == superClassCandidate) return false;
+ final PsiSubstitutor superSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(superClassCandidate, derivedClass,
+ PsiSubstitutor.EMPTY, null);
+ if (superSubstitutor == null) return false;
final MethodSignature superSignature = superMethodCandidate.getSignature(superSubstitutor);
final MethodSignature derivedSignature = derivedMethod.getSignature(PsiSubstitutor.EMPTY);
return isSubsignature(superSignature, derivedSignature);
diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
index e5493711b7c2..a69e11a9d3cc 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
@@ -1099,6 +1099,11 @@ public final class PsiUtil extends PsiUtilCore {
return true;
}
}
+ else if (parent instanceof PsiConditionalExpression) {
+ if (checkSameExpression(expr, ((PsiConditionalExpression)parent).getCondition())) {
+ return true;
+ }
+ }
return false;
}
diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
index 477a74e64b2e..42f1494bad2e 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
@@ -128,6 +128,9 @@ public class TypeConversionUtil {
return boxedType != null && areTypesConvertible(boxedType, toType);
}
if (!fromIsPrimitive) {
+ // 5.5. Casting Contexts
+ if ((fromTypeRank == SHORT_RANK || fromTypeRank == BYTE_RANK) && toTypeRank == CHAR_RANK) return false;
+
if (fromType instanceof PsiClassType) {
if (languageLevel == null) {
languageLevel = ((PsiClassType)fromType).getLanguageLevel();
@@ -162,7 +165,7 @@ public class TypeConversionUtil {
/**
* see JLS 5.1.5, JLS3 5.1.6
*/
- private static boolean isNarrowingReferenceConversionAllowed(PsiType fromType, PsiType toType) {
+ private static boolean isNarrowingReferenceConversionAllowed(@NotNull PsiType fromType, @NotNull PsiType toType) {
if (toType instanceof PsiPrimitiveType || fromType instanceof PsiPrimitiveType) return fromType.equals(toType);
//Done with primitives
if (toType instanceof PsiDiamondType || fromType instanceof PsiDiamondType) return false;
@@ -280,60 +283,56 @@ public class TypeConversionUtil {
return false;
}
}
- else {
- if (!toClass.isInterface()) {
- if (!toClass.hasModifierProperty(PsiModifier.FINAL)) {
- return checkSuperTypesWithDifferentTypeArguments(fromResult, toClass, manager, toResult.getSubstitutor(), null, languageLevel);
- }
- else {
- if (!toClass.isInheritor(fromClass, true)) return false;
- PsiSubstitutor toSubstitutor = getSuperClassSubstitutor(fromClass, toClass, toResult.getSubstitutor());
- return areSameArgumentTypes(fromClass, fromResult.getSubstitutor(), toSubstitutor);
- }
+ else if (!toClass.isInterface()) {
+ if (!toClass.hasModifierProperty(PsiModifier.FINAL)) {
+ return checkSuperTypesWithDifferentTypeArguments(fromResult, toClass, manager, toResult.getSubstitutor(), null, languageLevel);
}
else {
- if (languageLevel.compareTo(LanguageLevel.JDK_1_5) < 0) {
- //In jls2 check for method in both interfaces with the same signature but different return types.
- Collection<HierarchicalMethodSignature> fromClassMethodSignatures = fromClass.getVisibleSignatures();
- Collection<HierarchicalMethodSignature> toClassMethodSignatures = toClass.getVisibleSignatures();
-
- for (HierarchicalMethodSignature fromMethodSignature : fromClassMethodSignatures) {
- for (HierarchicalMethodSignature toMethodSignature : toClassMethodSignatures) {
- if (fromMethodSignature.equals(toMethodSignature)) {
- final PsiType fromClassReturnType = fromMethodSignature.getMethod().getReturnType();
- final PsiType toClassReturnType = toMethodSignature.getMethod().getReturnType();
- if (fromClassReturnType != null
- && toClassReturnType != null
- && !fromClassReturnType.equals(toClassReturnType)) {
- return false;
- }
- }
+ PsiSubstitutor toSubstitutor = getMaybeSuperClassSubstitutor(fromClass, toClass, toResult.getSubstitutor(), null);
+ return toSubstitutor != null && areSameArgumentTypes(fromClass, fromResult.getSubstitutor(), toSubstitutor);
+ }
+ }
+ else if (languageLevel.compareTo(LanguageLevel.JDK_1_5) < 0) {
+ //In jls2 check for method in both interfaces with the same signature but different return types.
+ Collection<HierarchicalMethodSignature> fromClassMethodSignatures = fromClass.getVisibleSignatures();
+ Collection<HierarchicalMethodSignature> toClassMethodSignatures = toClass.getVisibleSignatures();
+
+ for (HierarchicalMethodSignature fromMethodSignature : fromClassMethodSignatures) {
+ for (HierarchicalMethodSignature toMethodSignature : toClassMethodSignatures) {
+ if (fromMethodSignature.equals(toMethodSignature)) {
+ final PsiType fromClassReturnType = fromMethodSignature.getMethod().getReturnType();
+ final PsiType toClassReturnType = toMethodSignature.getMethod().getReturnType();
+ if (fromClassReturnType != null
+ && toClassReturnType != null
+ && !fromClassReturnType.equals(toClassReturnType)) {
+ return false;
}
}
- return true;
- }
- else {
- //In jls3 check for super interface with distinct type arguments
- PsiClassType.ClassResolveResult baseResult;
- PsiClass derived;
- PsiSubstitutor derivedSubstitutor;
- if (toClass.isInheritor(fromClass, true)) {
- baseResult = fromResult;
- derived = toClass;
- derivedSubstitutor = toResult.getSubstitutor();
- }
- else {
- baseResult = toResult;
- derived = fromClass;
- derivedSubstitutor = fromResult.getSubstitutor();
- }
- return checkSuperTypesWithDifferentTypeArguments(baseResult, derived, manager, derivedSubstitutor, null, languageLevel);
}
}
+ return true;
+ }
+ else {
+ //In jls3 check for super interface with distinct type arguments
+ PsiClassType.ClassResolveResult baseResult;
+ PsiClass derived;
+ PsiSubstitutor derivedSubstitutor;
+ if (toClass.isInheritor(fromClass, true)) {
+ baseResult = fromResult;
+ derived = toClass;
+ derivedSubstitutor = toResult.getSubstitutor();
+ }
+ else {
+ baseResult = toResult;
+ derived = fromClass;
+ derivedSubstitutor = fromResult.getSubstitutor();
+ }
+ return checkSuperTypesWithDifferentTypeArguments(baseResult, derived, manager, derivedSubstitutor, null, languageLevel);
}
}
- private static PsiClassType obtainSafeSuperType(final PsiTypeParameter typeParameter) {
+ @NotNull
+ private static PsiClassType obtainSafeSuperType(@NotNull PsiTypeParameter typeParameter) {
final PsiClassType superType = typeParameter.getSuperTypes()[0];
final PsiClassType.ClassResolveResult result = superType.resolveGenerics();
final PsiClass superClass = result.getElement();
@@ -344,12 +343,12 @@ public class TypeConversionUtil {
return superType;
}
- private static boolean checkSuperTypesWithDifferentTypeArguments(PsiClassType.ClassResolveResult baseResult,
- PsiClass derived,
- PsiManager manager,
- PsiSubstitutor derivedSubstitutor,
+ private static boolean checkSuperTypesWithDifferentTypeArguments(@NotNull PsiClassType.ClassResolveResult baseResult,
+ @NotNull PsiClass derived,
+ @NotNull PsiManager manager,
+ @NotNull PsiSubstitutor derivedSubstitutor,
Set<PsiClass> visited,
- final LanguageLevel languageLevel) {
+ @NotNull LanguageLevel languageLevel) {
if (visited != null && visited.contains(derived)) return true;
if (languageLevel.compareTo(LanguageLevel.JDK_1_5) < 0) return true;
@@ -359,10 +358,12 @@ public class TypeConversionUtil {
derivedSubstitutor = getSuperClassSubstitutor(derived, derived, derivedSubstitutor);
return areSameArgumentTypes(derived, baseResult.getSubstitutor(), derivedSubstitutor, 1);
}
- else if (base.isInheritor(derived, true)) {
- derivedSubstitutor = getSuperClassSubstitutor(derived, derived, derivedSubstitutor);
- PsiSubstitutor baseSubstitutor = getSuperClassSubstitutor(derived, base, baseResult.getSubstitutor());
- if (!areSameArgumentTypes(derived, baseSubstitutor, derivedSubstitutor)) return false;
+ else {
+ PsiSubstitutor baseSubstitutor = getMaybeSuperClassSubstitutor(derived, base, baseResult.getSubstitutor(), null);
+ if (baseSubstitutor != null) {
+ derivedSubstitutor = getSuperClassSubstitutor(derived, derived, derivedSubstitutor);
+ if (!areSameArgumentTypes(derived, baseSubstitutor, derivedSubstitutor)) return false;
+ }
}
if (visited == null) visited = new THashSet<PsiClass>();
@@ -375,7 +376,7 @@ public class TypeConversionUtil {
return true;
}
- private static boolean areSameParameterTypes(PsiClassType type1, PsiClassType type2) {
+ private static boolean areSameParameterTypes(@NotNull PsiClassType type1, @NotNull PsiClassType type2) {
PsiClassType.ClassResolveResult resolveResult1 = type1.resolveGenerics();
PsiClassType.ClassResolveResult resolveResult2 = type2.resolveGenerics();
final PsiClass aClass = resolveResult1.getElement();
@@ -386,13 +387,13 @@ public class TypeConversionUtil {
areSameArgumentTypes(aClass, resolveResult1.getSubstitutor(), resolveResult2.getSubstitutor());
}
- private static boolean areSameArgumentTypes(PsiClass aClass, PsiSubstitutor substitutor1, PsiSubstitutor substitutor2) {
+ private static boolean areSameArgumentTypes(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor1, @NotNull PsiSubstitutor substitutor2) {
return areSameArgumentTypes(aClass, substitutor1, substitutor2, 0);
}
- private static boolean areSameArgumentTypes(PsiClass aClass,
- PsiSubstitutor substitutor1,
- PsiSubstitutor substitutor2,
+ private static boolean areSameArgumentTypes(@NotNull PsiClass aClass,
+ @NotNull PsiSubstitutor substitutor1,
+ @NotNull PsiSubstitutor substitutor2,
int level) {
for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(aClass)) {
PsiType typeArg1 = substitutor1.substitute(typeParameter);
@@ -463,7 +464,7 @@ public class TypeConversionUtil {
* STRING_TYPE for String,
* Integer.MAX_VALUE for others
*/
- public static int getTypeRank(PsiType type) {
+ public static int getTypeRank(@NotNull PsiType type) {
PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(type);
if (unboxedType != null) {
type = unboxedType;
@@ -597,13 +598,13 @@ public class TypeConversionUtil {
return isPrimitiveAndNotNull(type);
}
- public static boolean isUnaryOperatorApplicable(PsiJavaToken token, PsiExpression operand) {
+ public static boolean isUnaryOperatorApplicable(@NotNull PsiJavaToken token, PsiExpression operand) {
if (operand == null) return false;
PsiType type = operand.getType();
return type != null && isUnaryOperatorApplicable(token, type);
}
- public static boolean isUnaryOperatorApplicable(final PsiJavaToken token, final PsiType type) {
+ public static boolean isUnaryOperatorApplicable(@NotNull PsiJavaToken token, @NotNull PsiType type) {
IElementType i = token.getTokenType();
int typeRank = getTypeRank(type);
if (i == JavaTokenType.MINUSMINUS || i == JavaTokenType.PLUSPLUS) {
@@ -672,7 +673,7 @@ public class TypeConversionUtil {
value = ((Number)rValue).longValue();
}
else if (rValue instanceof Character) {
- value = ((Character)rValue).charValue();
+ value = (Character)rValue;
}
else {
return false;
@@ -832,7 +833,7 @@ public class TypeConversionUtil {
return isClassAssignable(leftResult, rightResult, allowUncheckedConversion);
}
- private static boolean isAssignableFromWildcard(PsiType left, PsiWildcardType rightWildcardType) {
+ private static boolean isAssignableFromWildcard(@NotNull PsiType left, @NotNull PsiWildcardType rightWildcardType) {
if (rightWildcardType.isSuper()) {
final PsiClass aClass = PsiUtil.resolveClassInType(rightWildcardType.getSuperBound());
if (aClass instanceof PsiTypeParameter) {
@@ -845,14 +846,14 @@ public class TypeConversionUtil {
return isAssignable(left, rightWildcardType.getExtendsBound());
}
- private static boolean isAssignableToWildcard(PsiWildcardType wildcardType, PsiType right) {
+ private static boolean isAssignableToWildcard(@NotNull PsiWildcardType wildcardType, @NotNull PsiType right) {
if (wildcardType.isSuper()) {
return isAssignable(wildcardType.getSuperBound(), right);
}
return isAssignable(wildcardType.getExtendsBound(), right);
}
- private static boolean isUnboxable(final PsiPrimitiveType left, final PsiClassType right) {
+ private static boolean isUnboxable(@NotNull PsiPrimitiveType left, @NotNull PsiClassType right) {
final PsiPrimitiveType rightUnboxedType = PsiPrimitiveType.getUnboxedType(right);
return rightUnboxedType != null && isAssignable(left, rightUnboxedType);
}
@@ -869,7 +870,7 @@ public class TypeConversionUtil {
private static final Key<CachedValue<Set<String>>> POSSIBLE_BOXED_HOLDER_TYPES = Key.create("Types that may be possibly assigned from primitive ones");
- private static boolean isBoxable(final PsiClassType left, final PsiPrimitiveType right) {
+ private static boolean isBoxable(@NotNull PsiClassType left, @NotNull PsiPrimitiveType right) {
if (!left.getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_5)) return false;
final PsiClass psiClass = left.resolve();
if (psiClass == null) return false;
@@ -883,7 +884,8 @@ public class TypeConversionUtil {
return rightBoxed != null && isAssignable(left, rightBoxed);
}
- private static Set<String> getAllBoxedTypeSupers(PsiClass psiClass) {
+ @NotNull
+ private static Set<String> getAllBoxedTypeSupers(@NotNull PsiClass psiClass) {
PsiManager manager = psiClass.getManager();
final Project project = psiClass.getProject();
CachedValue<Set<String>> boxedHolderTypes = project.getUserData(POSSIBLE_BOXED_HOLDER_TYPES);
@@ -908,12 +910,11 @@ public class TypeConversionUtil {
}, false));
}
- final Set<String> boxedHolders = boxedHolderTypes.getValue();
- return boxedHolders;
+ return boxedHolderTypes.getValue();
}
- private static boolean isClassAssignable(PsiClassType.ClassResolveResult leftResult,
- PsiClassType.ClassResolveResult rightResult,
+ private static boolean isClassAssignable(@NotNull PsiClassType.ClassResolveResult leftResult,
+ @NotNull PsiClassType.ClassResolveResult rightResult,
boolean allowUncheckedConversion) {
final PsiClass leftClass = leftResult.getElement();
final PsiClass rightClass = rightResult.getElement();
@@ -923,8 +924,8 @@ public class TypeConversionUtil {
&& typeParametersAgree(leftResult, rightResult, allowUncheckedConversion);
}
- private static boolean typeParametersAgree(PsiClassType.ClassResolveResult leftResult,
- PsiClassType.ClassResolveResult rightResult,
+ private static boolean typeParametersAgree(@NotNull PsiClassType.ClassResolveResult leftResult,
+ @NotNull PsiClassType.ClassResolveResult rightResult,
boolean allowUncheckedConversion) {
PsiSubstitutor rightSubstitutor = rightResult.getSubstitutor();
PsiClass leftClass = leftResult.getElement();
@@ -962,7 +963,7 @@ public class TypeConversionUtil {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("isAssignable");
- public static boolean typesAgree(PsiType typeLeft, PsiType typeRight, final boolean allowUncheckedConversion) {
+ public static boolean typesAgree(@NotNull PsiType typeLeft, @NotNull PsiType typeRight, final boolean allowUncheckedConversion) {
if (typeLeft instanceof PsiWildcardType) {
final PsiWildcardType leftWildcard = (PsiWildcardType)typeLeft;
final PsiType leftBound = leftWildcard.getBound();
@@ -986,7 +987,7 @@ public class TypeConversionUtil {
return isAssignable(rightWildcard.getBound(), leftBound, allowUncheckedConversion);
}
});
- if (assignable != null && assignable.booleanValue()) {
+ if (assignable != null && assignable) {
return true;
}
}
@@ -1022,7 +1023,7 @@ public class TypeConversionUtil {
@Nullable
public static PsiSubstitutor getClassSubstitutor(@NotNull PsiClass superClassCandidate,
@NotNull PsiClass derivedClassCandidate,
- PsiSubstitutor derivedSubstitutor) {
+ @NotNull PsiSubstitutor derivedSubstitutor) {
if (superClassCandidate.getManager().areElementsEquivalent(superClassCandidate, derivedClassCandidate)) {
PsiTypeParameter[] baseParams = superClassCandidate.getTypeParameters();
PsiTypeParameter[] derivedParams = derivedClassCandidate.getTypeParameters();
@@ -1031,8 +1032,7 @@ public class TypeConversionUtil {
}
return derivedSubstitutor;
}
- if (!derivedClassCandidate.isInheritor(superClassCandidate, true)) return null;
- return getSuperClassSubstitutor(superClassCandidate, derivedClassCandidate, derivedSubstitutor);
+ return getMaybeSuperClassSubstitutor(superClassCandidate, derivedClassCandidate, derivedSubstitutor, null);
}
private static final Set<String> ourReportedSuperClassSubstitutorExceptions = new ConcurrentHashSet<String>();
@@ -1042,52 +1042,61 @@ public class TypeConversionUtil {
* values that they have in <code>derivedClass</code>, given that type parameters in
* <code>derivedClass</code> are bound by <code>derivedSubstitutor</code>.
* <code>superClass</code> must be a super class/interface of <code>derivedClass</code> (as in
- * <code>InheritanceUtil.isInheritor(derivedClass, superClass, true)</code>
+ * <code>InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true)</code>
*
* @return substitutor (never returns <code>null</code>)
* @see PsiClass#isInheritor(PsiClass, boolean)
+ * @see InheritanceUtil#isInheritorOrSelf(com.intellij.psi.PsiClass, com.intellij.psi.PsiClass, boolean)
*/
@NotNull
public static PsiSubstitutor getSuperClassSubstitutor(@NotNull PsiClass superClass,
@NotNull PsiClass derivedClass,
@NotNull PsiSubstitutor derivedSubstitutor) {
- // [dsl] assertion commented out since we no longer cache isInheritor
- //LOG.assertTrue(derivedClass.isInheritor(superClass, true), "Not inheritor: " + derivedClass + " super: " + superClass);
+ if (!superClass.hasTypeParameters() && superClass.getContainingClass() == null) return PsiSubstitutor.EMPTY; //optimization and protection against EJB queer hierarchy
+
+ Set<PsiClass> visited = new THashSet<PsiClass>();
+ PsiSubstitutor substitutor = getMaybeSuperClassSubstitutor(superClass, derivedClass, derivedSubstitutor, visited);
+
+ if (substitutor == null) {
+ if (ourReportedSuperClassSubstitutorExceptions.add(derivedClass.getQualifiedName() + "/" + superClass.getQualifiedName())) {
+ reportHierarchyInconsistency(superClass, derivedClass, visited);
+ }
+ return PsiSubstitutor.EMPTY;
+ }
+ return substitutor;
+ }
- if (!superClass.hasTypeParameters() && superClass.getContainingClass() == null) return PsiSubstitutor.EMPTY; //optimization
+ // the same as getSuperClassSubstitutor() but can return null, which means that classes were not inheritors
+ @Nullable
+ public static PsiSubstitutor getMaybeSuperClassSubstitutor(@NotNull PsiClass superClass,
+ @NotNull PsiClass derivedClass,
+ @NotNull PsiSubstitutor derivedSubstitutor,
+ @Nullable Set<PsiClass> visited) {
+ if (!superClass.hasTypeParameters() && superClass.getContainingClass() == null) {
+ return InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true) ? PsiSubstitutor.EMPTY : null; //optimization
+ }
final PsiManager manager = superClass.getManager();
if (PsiUtil.isRawSubstitutor(derivedClass, derivedSubstitutor)) {
- return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createRawSubstitutor(superClass);
+ return InheritanceUtil.isInheritorOrSelf(derivedClass, superClass, true) ? JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createRawSubstitutor(superClass) : null;
}
- final PsiClass objectClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, superClass.getResolveScope());
- if (manager.areElementsEquivalent(superClass, objectClass)) {
+ if (CommonClassNames.JAVA_LANG_OBJECT_SHORT.equals(superClass.getName()) &&
+ manager.areElementsEquivalent(superClass, JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, superClass.getResolveScope()))) {
return PsiSubstitutor.EMPTY;
}
- PsiSubstitutor substitutor;
- final Set<PsiClass> visited = new THashSet<PsiClass>();
if (derivedClass instanceof PsiAnonymousClass) {
final PsiClassType baseType = ((PsiAnonymousClass)derivedClass).getBaseClassType();
final JavaResolveResult result = baseType.resolveGenerics();
if (result.getElement() == null) return PsiSubstitutor.UNKNOWN;
- substitutor = getSuperClassSubstitutorInner(superClass, (PsiClass)result.getElement(),
- derivedSubstitutor.putAll(result.getSubstitutor()), visited, manager);
- }
- else {
- substitutor = getSuperClassSubstitutorInner(superClass, derivedClass, derivedSubstitutor, visited, manager);
+ derivedClass = (PsiClass)result.getElement();
+ derivedSubstitutor = derivedSubstitutor.putAll(result.getSubstitutor());
}
- if (substitutor == null) {
- if (ourReportedSuperClassSubstitutorExceptions.add(derivedClass.getQualifiedName() + "/" + superClass.getQualifiedName())) {
- reportHierarchyInconsistency(superClass, derivedClass, visited);
- }
- return PsiSubstitutor.EMPTY;
- }
- return substitutor;
+ return getSuperClassSubstitutorInner(superClass, derivedClass, derivedSubstitutor, visited == null ? new THashSet<PsiClass>() : visited, manager);
}
- private static void reportHierarchyInconsistency(PsiClass superClass, PsiClass derivedClass, Set<PsiClass> visited) {
+ private static void reportHierarchyInconsistency(@NotNull PsiClass superClass, @NotNull PsiClass derivedClass, @NotNull Set<PsiClass> visited) {
final StringBuilder msg = new StringBuilder("Super: " + classInfo(superClass));
msg.append("visited:\n");
for (PsiClass aClass : visited) {
@@ -1105,7 +1114,8 @@ public class TypeConversionUtil {
LOG.error(msg.toString());
}
- private static String classInfo(PsiClass aClass) {
+ @NotNull
+ private static String classInfo(@NotNull PsiClass aClass) {
String s = aClass.getQualifiedName() + "(" + aClass.getClass().getName() + "; " + PsiUtilCore.getVirtualFile(aClass) + ");\n";
s += "extends: ";
for (PsiClassType type : aClass.getExtendsListTypes()) {
@@ -1124,12 +1134,14 @@ public class TypeConversionUtil {
return getSuperClassSubstitutor(superClass, classResolveResult.getElement(), classResolveResult.getSubstitutor());
}
- private static PsiSubstitutor getSuperClassSubstitutorInner(PsiClass base,
- PsiClass candidate,
- PsiSubstitutor candidateSubstitutor,
- Set<PsiClass> visited,
- PsiManager manager) {
+ @Nullable
+ private static PsiSubstitutor getSuperClassSubstitutorInner(@NotNull PsiClass base,
+ @NotNull PsiClass candidate,
+ @NotNull PsiSubstitutor candidateSubstitutor,
+ @NotNull Set<PsiClass> visited,
+ @NotNull PsiManager manager) {
if (!visited.add(candidate)) return null;
+ assert candidateSubstitutor.isValid();
if (base == candidate) return candidateSubstitutor;
if (manager.areElementsEquivalent(base, candidate)) {
@@ -1148,19 +1160,18 @@ public class TypeConversionUtil {
}
}
- PsiSubstitutor substitutor = checkReferenceList(candidate.getExtendsListTypes(), candidateSubstitutor, base, visited,
- manager);
+ PsiSubstitutor substitutor = checkReferenceList(candidate.getExtendsListTypes(), candidateSubstitutor, base, visited, manager);
if (substitutor == null) {
substitutor = checkReferenceList(candidate.getImplementsListTypes(), candidateSubstitutor, base, visited, manager);
}
return substitutor;
}
- private static PsiSubstitutor checkReferenceList(final PsiClassType[] types, PsiSubstitutor candidateSubstitutor,
- PsiClass base,
- Set<PsiClass> set,
- PsiManager manager) {
- assert candidateSubstitutor.isValid();
+ private static PsiSubstitutor checkReferenceList(@NotNull PsiClassType[] types,
+ @NotNull PsiSubstitutor candidateSubstitutor,
+ @NotNull PsiClass base,
+ @NotNull Set<PsiClass> set,
+ @NotNull PsiManager manager) {
for (final PsiClassType type : types) {
final PsiType substitutedType = candidateSubstitutor.substitute(type);
//if (!(substitutedType instanceof PsiClassType)) return null;
@@ -1170,8 +1181,7 @@ public class TypeConversionUtil {
final PsiElement newCandidate = result.getElement();
if (newCandidate != null) {
final PsiSubstitutor substitutor = result.getSubstitutor();
- final PsiSubstitutor newSubstitutor = getSuperClassSubstitutorInner(base, (PsiClass)newCandidate,
- substitutor, set, manager);
+ final PsiSubstitutor newSubstitutor = getSuperClassSubstitutorInner(base, (PsiClass)newCandidate, substitutor, set, manager);
if (newSubstitutor != null) {
return type.isRaw() ? JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createRawSubstitutor(base) : newSubstitutor;
}
@@ -1183,6 +1193,7 @@ public class TypeConversionUtil {
/**
* see JLS 5.6.2
*/
+ @NotNull
public static PsiType binaryNumericPromotion(PsiType type1, PsiType type2) {
if (isDoubleType(type1)) return unbox(type1);
if (isDoubleType(type2)) return unbox(type2);
@@ -1194,7 +1205,8 @@ public class TypeConversionUtil {
return PsiType.INT;
}
- private static PsiType unbox(PsiType type) {
+ @NotNull
+ private static PsiType unbox(@NotNull PsiType type) {
if (type instanceof PsiPrimitiveType) return type;
if (type instanceof PsiClassType) {
type = PsiPrimitiveType.getUnboxedType(type);
@@ -1393,6 +1405,7 @@ public class TypeConversionUtil {
return value;
}
+ @NotNull
public static PsiType unboxAndBalanceTypes(PsiType type1, PsiType type2) {
if (type1 instanceof PsiClassType) type1 = PsiPrimitiveType.getUnboxedType(type1);
if (type2 instanceof PsiClassType) type2 = PsiPrimitiveType.getUnboxedType(type2);
@@ -1442,7 +1455,7 @@ public class TypeConversionUtil {
}
@Nullable
- public static PsiType calcTypeForBinaryExpression(PsiType lType, PsiType rType, IElementType sign, boolean accessLType) {
+ public static PsiType calcTypeForBinaryExpression(PsiType lType, PsiType rType, @NotNull IElementType sign, boolean accessLType) {
if (sign == JavaTokenType.PLUS) {
// evaluate right argument first, since '+-/*%' is left associative and left operand tends to be bigger
if (rType == null) return null;
@@ -1512,321 +1525,371 @@ public class TypeConversionUtil {
}
private interface Caster {
- Object cast(Object operand);
+ @NotNull
+ Object cast(@NotNull Object operand);
}
private static final Caster[][] caster = {
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
+ public Object cast(@NotNull Object operand) {
return operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf((short)((Number)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (short)((Number)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character((char) ((Number) operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (char)((Number)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf(((Number)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return ((Number)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf(((Number)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (long)((Number)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Number) operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (float)((Number)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Number) operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (double)((Number)operand).intValue();
}
}
}
,
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Byte.valueOf((byte)((Short)operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return (byte)((Short)operand).shortValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf(((Short)operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character((char) ((Short) operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return (char)((Short)operand).shortValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf(((Short)operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return (int)(Short)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf(((Short)operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return (long)(Short)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Short) operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return (float)(Short)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Short) operand).shortValue());
+ public Object cast(@NotNull Object operand) {
+ return (double)(Short)operand;
}
}
}
,
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Byte.valueOf((byte)((Character)operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return (byte)((Character)operand).charValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf((short)((Character)operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return (short)((Character)operand).charValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character(((Character) operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf(((Character)operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return (int)(Character)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf(((Character)operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return (long)(Character)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Character) operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return (float)(Character)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Character) operand).charValue());
+ public Object cast(@NotNull Object operand) {
+ return (double)(Character)operand;
}
}
}
,
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Byte.valueOf((byte)((Integer)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (byte)((Integer)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf((short)((Integer)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (short)((Integer)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character((char) ((Integer) operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (char)((Integer)operand).intValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf(((Integer)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf(((Integer)operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (long)(Integer)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Integer) operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (float)(Integer)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Integer) operand).intValue());
+ public Object cast(@NotNull Object operand) {
+ return (double)(Integer)operand;
}
}
}
,
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Byte.valueOf((byte)((Long)operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return (byte)((Long)operand).longValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf((short)((Long)operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return (short)((Long)operand).longValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character((char) ((Long) operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return (char)((Long)operand).longValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf((int)((Long)operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return (int)((Long)operand).longValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf(((Long)operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Long) operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return (float)(Long)operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Long) operand).longValue());
+ public Object cast(@NotNull Object operand) {
+ return (double)(Long)operand;
}
}
}
,
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Byte.valueOf((byte)((Float)operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return (byte)((Float)operand).floatValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf((short)((Float)operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return (short)((Float)operand).floatValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character((char) ((Float) operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return (char)((Float)operand).floatValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf((int)((Float)operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return (int)((Float)operand).floatValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf((long)((Float)operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return (long)((Float)operand).floatValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Float) operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return operand;
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Float) operand).floatValue());
+ public Object cast(@NotNull Object operand) {
+ return (double)(Float)operand;
}
}
}
,
{
new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Byte.valueOf((byte)((Double)operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return (byte)((Double)operand).doubleValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Short.valueOf((short)((Double)operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return (short)((Double)operand).doubleValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Character((char) ((Double) operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return (char)((Double)operand).doubleValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Integer.valueOf((int)((Double)operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return (int)((Double)operand).doubleValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return Long.valueOf((long)((Double)operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return (long)((Double)operand).doubleValue();
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Float(((Double) operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return new Float((Double)operand);
}
}
, new Caster() {
+ @NotNull
@Override
- public Object cast(Object operand) {
- return new Double(((Double) operand).doubleValue());
+ public Object cast(@NotNull Object operand) {
+ return operand;
}
}
}
@@ -1844,7 +1907,7 @@ public class TypeConversionUtil {
WRAPPER_TO_PRIMITIVE.put(Double.class, PsiType.DOUBLE);
}
- private static PsiType wrapperToPrimitive(Object o) {
+ private static PsiType wrapperToPrimitive(@NotNull Object o) {
return WRAPPER_TO_PRIMITIVE.get(o.getClass());
}
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/CustomExceptionHandler.java b/java/java-psi-impl/src/com/intellij/codeInsight/CustomExceptionHandler.java
new file mode 100644
index 000000000000..7678390d0356
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/CustomExceptionHandler.java
@@ -0,0 +1,13 @@
+package com.intellij.codeInsight;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiClassType;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class CustomExceptionHandler {
+ public static final ExtensionPointName<CustomExceptionHandler> KEY = ExtensionPointName.create("com.intellij.custom.exception.handler");
+
+ public abstract boolean isHandled(@Nullable PsiElement element, @NotNull PsiClassType exceptionType, PsiElement topElement);
+}
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java
index 552c7e2d9ff5..bb4e322a2eec 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight;
+import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.controlFlow.*;
@@ -675,6 +676,10 @@ public class ExceptionUtil {
// exceptions thrown in field initializers should be thrown in all class constructors
return areAllConstructorsThrow(aClass, exceptionType);
}
+ } else {
+ for (CustomExceptionHandler exceptionHandler : Extensions.getExtensions(CustomExceptionHandler.KEY)) {
+ if (exceptionHandler.isHandled(element, exceptionType, topElement)) return true;
+ }
}
return isHandled(parent, exceptionType, topElement);
}
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
index 5e008afb4797..e2de5a55e0b3 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
@@ -598,9 +598,15 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
Document document = method.getContainingFile().getViewProvider().getDocument();
PsiCodeBlock body = method.getBody();
- if (body == null || document == null) {
+ PsiIdentifier nameIdentifier = method.getNameIdentifier();
+ if (body == null || document == null || nameIdentifier == null) {
return false;
}
+ if (document.getLineNumber(nameIdentifier.getTextRange().getStartOffset()) !=
+ document.getLineNumber(method.getParameterList().getTextRange().getEndOffset())) {
+ return false;
+ }
+
PsiJavaToken lBrace = body.getLBrace();
PsiJavaToken rBrace = body.getRBrace();
PsiStatement[] statements = body.getStatements();
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/ParameterNameFoldingManager.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/ParameterNameFoldingManager.java
index aca4357f7e49..a8b2b40111ba 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/ParameterNameFoldingManager.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/ParameterNameFoldingManager.java
@@ -39,7 +39,8 @@ public class ParameterNameFoldingManager {
Couple.of("first", "last"),
Couple.of("first", "second"),
Couple.of("from", "to"),
- Couple.of("key", "value")
+ Couple.of("key", "value"),
+ Couple.of("min", "max")
);
private final PsiCallExpression myCallExpression;
@@ -58,7 +59,8 @@ public class ParameterNameFoldingManager {
if (callArgument instanceof PsiPrefixExpression) {
PsiPrefixExpression expr = (PsiPrefixExpression)callArgument;
IElementType tokenType = expr.getOperationTokenType();
- return JavaTokenType.MINUS.equals(tokenType) && expr.getOperand() instanceof PsiLiteralExpression;
+ return (JavaTokenType.MINUS.equals(tokenType)
+ || JavaTokenType.PLUS.equals(tokenType)) && expr.getOperand() instanceof PsiLiteralExpression;
}
return false;
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/ColorUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/ColorUtil.java
index f7094421b980..ac2fe33d0e43 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/ColorUtil.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/ColorUtil.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,10 +17,10 @@ package com.intellij.codeInsight.javadoc;
import com.intellij.psi.*;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.ReflectionUtil;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
-import java.lang.reflect.Field;
/**
* @author spleaner
@@ -98,14 +98,12 @@ public class ColorUtil {
if (reference != null) {
final PsiElement psiElement = reference.resolve();
if (psiElement instanceof PsiField) {
- final PsiClass psiClass = ((PsiField) psiElement).getContainingClass();
+ PsiField psiField = (PsiField)psiElement;
+ final PsiClass psiClass = psiField.getContainingClass();
if (psiClass != null && "java.awt.Color".equals(psiClass.getQualifiedName())) {
- try {
- Field field = Class.forName("java.awt.Color").getField(((PsiField)psiElement).getName());
- final Color c = (Color) field.get(null);
+ Color c = ReflectionUtil.getField(Color.class, null, Color.class, psiField.getName());
+ if (c != null) {
buffer.append(generatePreviewHtml(c));
- } catch (Exception e) {
- // nothing
}
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java b/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java
index e1116894f14f..5f3eee5c6be3 100644
--- a/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java
@@ -34,6 +34,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.VisibilityUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -253,8 +254,9 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
PsiTypeParameter[] params,
PsiJavaCodeReferenceElement reference) {
final StringBuilder buf = new StringBuilder();
- buf.append(constructor != null ? constructor.getModifierList().getText() : containingClass.getModifierList().getText());
- if (buf.length() > 0) {
+ final String modifier = VisibilityUtil.getVisibilityModifier(constructor != null ? constructor.getModifierList() : containingClass.getModifierList());
+ if (!PsiModifier.PACKAGE_LOCAL.equals(modifier)) {
+ buf.append(modifier);
buf.append(" ");
}
buf.append("static ");
@@ -262,8 +264,20 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
buf.append(StringUtil.join(params, new Function<PsiTypeParameter, String>() {
@Override
public String fun(PsiTypeParameter psiTypeParameter) {
- final String extendsList = psiTypeParameter.getLanguage().isKindOf(JavaLanguage.INSTANCE) ? psiTypeParameter.getExtendsList().getText() : null;
- return psiTypeParameter.getName() + (StringUtil.isEmpty(extendsList) ? "" : " " + extendsList);
+ String extendsList = "";
+ if (psiTypeParameter.getLanguage().isKindOf(JavaLanguage.INSTANCE)) {
+ final PsiClassType[] extendsListTypes = psiTypeParameter.getExtendsListTypes();
+ if (extendsListTypes.length > 0) {
+ final Function<PsiClassType, String> canonicalTypePresentationFun = new Function<PsiClassType, String>() {
+ @Override
+ public String fun(PsiClassType type) {
+ return type.getCanonicalText();
+ }
+ };
+ extendsList = " extends " + StringUtil.join(extendsListTypes, canonicalTypePresentationFun, "&");
+ }
+ }
+ return psiTypeParameter.getName() + extendsList;
}
}, ", "));
buf.append(">");
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/InheritanceImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/InheritanceImplUtil.java
index f958555a3c45..9427551aacf8 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/InheritanceImplUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/InheritanceImplUtil.java
@@ -25,9 +25,7 @@ import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.containers.ConcurrentWeakHashMap;
-import com.intellij.util.containers.HashSet;
import gnu.trove.THashSet;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -39,10 +37,12 @@ public class InheritanceImplUtil {
public static boolean isInheritor(@NotNull final PsiClass candidateClass, @NotNull PsiClass baseClass, final boolean checkDeep) {
if (baseClass instanceof PsiAnonymousClass) return false;
- if (!checkDeep) return isInheritor(candidateClass, baseClass, false, null);
+ if (!checkDeep) {
+ return isInheritor(candidateClass.getManager(), candidateClass, baseClass, false, null);
+ }
- if (CommonClassNames.JAVA_LANG_OBJECT_SHORT.equals(candidateClass.getName()) && CommonClassNames.JAVA_LANG_OBJECT.equals(candidateClass.getQualifiedName())) return false;
- if (CommonClassNames.JAVA_LANG_OBJECT_SHORT.equals(baseClass.getName()) && CommonClassNames.JAVA_LANG_OBJECT.equals(baseClass.getQualifiedName())) return true;
+ if (hasObjectQualifiedName(candidateClass)) return false;
+ if (hasObjectQualifiedName(baseClass)) return true;
Map<PsiClass, Boolean> map = CachedValuesManager.
getCachedValue(candidateClass, new CachedValueProvider<Map<PsiClass, Boolean>>() {
@Nullable
@@ -55,18 +55,29 @@ public class InheritanceImplUtil {
Boolean computed = map.get(baseClass);
if (computed == null) {
- computed = isInheritor(candidateClass, baseClass, true, null);
+ computed = isInheritor(candidateClass.getManager(), candidateClass, baseClass, true, null);
map.put(baseClass, computed);
}
return computed;
}
- private static boolean isInheritor(@NotNull PsiClass candidateClass, @NotNull PsiClass baseClass, boolean checkDeep, Set<PsiClass> checkedClasses) {
+ public static boolean hasObjectQualifiedName(@NotNull PsiClass candidateClass) {
+ if (!CommonClassNames.JAVA_LANG_OBJECT_SHORT.equals(candidateClass.getName())) {
+ return false;
+ }
+ PsiElement parent = candidateClass.getParent();
+ return parent instanceof PsiJavaFile && CommonClassNames.DEFAULT_PACKAGE.equals(((PsiJavaFile)parent).getPackageName());
+ }
+
+ private static boolean isInheritor(@NotNull PsiManager manager,
+ @NotNull PsiClass candidateClass,
+ @NotNull PsiClass baseClass,
+ boolean checkDeep,
+ @Nullable Set<PsiClass> checkedClasses) {
if (candidateClass instanceof PsiAnonymousClass) {
final PsiClass baseCandidateClass = ((PsiAnonymousClass)candidateClass).getBaseClassType().resolve();
return baseCandidateClass != null && InheritanceUtil.isInheritorOrSelf(baseCandidateClass, baseClass, checkDeep);
}
- PsiManager manager = candidateClass.getManager();
/* //TODO fix classhashprovider so it doesn't use class qnames only
final ClassHashProvider provider = getHashProvider((PsiManagerImpl) manager);
if (checkDeep && provider != null) {
@@ -81,8 +92,7 @@ public class InheritanceImplUtil {
LOG.debug("Using uncached version for " + candidateClass.getQualifiedName() + " and " + baseClass);
}
- @NonNls final String baseName = baseClass.getName();
- if (CommonClassNames.JAVA_LANG_OBJECT_SHORT.equals(baseName)) {
+ if (hasObjectQualifiedName(baseClass)) {
PsiClass objectClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, candidateClass.getResolveScope());
if (manager.areElementsEquivalent(baseClass, objectClass)) {
if (manager.areElementsEquivalent(candidateClass, objectClass)) return false;
@@ -103,6 +113,7 @@ public class InheritanceImplUtil {
if (cInt == bInt && checkReferenceListWithQualifiedNames(baseQName, candidateClass.getExtendsList(), manager, scope)) return true;
return bInt && !cInt && checkReferenceListWithQualifiedNames(baseQName, candidateClass.getImplementsList(), manager, scope);
}
+ String baseName = baseClass.getName();
if (cInt == bInt) {
for (PsiClassType type : candidateClass.getExtendsListTypes()) {
if (Comparing.equal(type.getClassName(), baseName)) {
@@ -125,7 +136,7 @@ public class InheritanceImplUtil {
return false;
}
- return isInheritorWithoutCaching(candidateClass, baseClass, checkDeep, checkedClasses);
+ return isInheritorWithoutCaching(manager, candidateClass, baseClass, checkedClasses);
}
private static boolean checkReferenceListWithQualifiedNames(final String baseQName, final PsiReferenceList extList, final PsiManager manager,
@@ -141,63 +152,50 @@ public class InheritanceImplUtil {
return false;
}
- private static boolean isInheritorWithoutCaching(PsiClass aClass, PsiClass baseClass, boolean checkDeep, Set<PsiClass> checkedClasses) {
- PsiManager manager = aClass.getManager();
+ private static boolean isInheritorWithoutCaching(@NotNull PsiManager manager,
+ @NotNull PsiClass aClass,
+ @NotNull PsiClass baseClass,
+ @Nullable Set<PsiClass> checkedClasses) {
if (manager.areElementsEquivalent(aClass, baseClass)) return false;
if (aClass.isInterface() && !baseClass.isInterface()) {
return false;
}
- //if (PsiUtil.hasModifierProperty(baseClass, PsiModifier.FINAL)) {
- // return false;
- //}
-
- if (checkDeep) {
- if (checkedClasses == null) {
- checkedClasses = new THashSet<PsiClass>();
- }
- checkedClasses.add(aClass);
+ if (checkedClasses == null) {
+ checkedClasses = new THashSet<PsiClass>();
}
+ checkedClasses.add(aClass);
- if (!aClass.isInterface() && baseClass.isInterface()) {
- if (checkDeep && checkInheritor(aClass.getSuperClass(), baseClass, checkDeep, checkedClasses)) {
- return true;
- }
- return checkInheritor(aClass.getInterfaces(), baseClass, checkDeep, checkedClasses);
-
- }
- else {
- return checkInheritor(aClass.getSupers(), baseClass, checkDeep, checkedClasses);
- }
+ return checkInheritor(manager, aClass.getExtendsListTypes(), baseClass, checkedClasses) ||
+ checkInheritor(manager, aClass.getImplementsListTypes(), baseClass, checkedClasses);
}
- private static boolean checkInheritor(PsiClass[] supers, PsiClass baseClass, boolean checkDeep, Set<PsiClass> checkedClasses) {
- for (PsiClass aSuper : supers) {
- if (checkInheritor(aSuper, baseClass, checkDeep, checkedClasses)) {
+ private static boolean checkInheritor(@NotNull PsiManager manager,
+ @NotNull PsiClassType[] supers,
+ @NotNull PsiClass baseClass,
+ @NotNull Set<PsiClass> checkedClasses) {
+ for (PsiClassType aSuper : supers) {
+ PsiClass aClass = aSuper.resolve();
+ if (aClass != null && checkInheritor(manager, aClass, baseClass, checkedClasses)) {
return true;
}
}
return false;
}
- private static boolean checkInheritor(PsiClass aClass, PsiClass baseClass, boolean checkDeep, Set<PsiClass> checkedClasses) {
+ private static boolean checkInheritor(@NotNull PsiManager manager,
+ @NotNull PsiClass aClass,
+ @NotNull PsiClass baseClass,
+ @NotNull Set<PsiClass> checkedClasses) {
ProgressIndicatorProvider.checkCanceled();
- if (aClass != null) {
- PsiManager manager = baseClass.getManager();
- if (manager.areElementsEquivalent(baseClass, aClass)) {
- return true;
- }
- if (checkedClasses != null && checkedClasses.contains(aClass)) { // to prevent infinite recursion
- return false;
- }
- if (checkDeep) {
- if (isInheritor(aClass, baseClass, checkDeep, checkedClasses)) {
- return true;
- }
- }
+ if (manager.areElementsEquivalent(baseClass, aClass)) {
+ return true;
}
- return false;
+ if (checkedClasses.contains(aClass)) { // to prevent infinite recursion
+ return false;
+ }
+ return isInheritor(manager, aClass, baseClass, true, checkedClasses);
}
public static boolean isInheritorDeep(@NotNull PsiClass candidateClass, @NotNull PsiClass baseClass, @Nullable final PsiClass classToByPass) {
@@ -207,9 +205,9 @@ public class InheritanceImplUtil {
Set<PsiClass> checkedClasses = null;
if (classToByPass != null) {
- checkedClasses = new HashSet<PsiClass>();
+ checkedClasses = new THashSet<PsiClass>();
checkedClasses.add(classToByPass);
}
- return isInheritor(candidateClass, baseClass, true, checkedClasses);
+ return isInheritor(candidateClass.getManager(), candidateClass, baseClass, true, checkedClasses);
}
}
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 514087492300..938b40f51bb8 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
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl;
+import com.intellij.codeInsight.AnnotationTargetUtil;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -51,7 +52,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -60,22 +60,6 @@ import static com.intellij.psi.PsiAnnotation.TargetType;
public class PsiImplUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiImplUtil");
- private static final Set<TargetType> DEFAULT_TARGETS = Collections.unmodifiableSet(ContainerUtil.newHashSet(
- TargetType.PACKAGE, TargetType.TYPE, TargetType.ANNOTATION_TYPE,
- TargetType.FIELD, TargetType.METHOD, TargetType.CONSTRUCTOR,
- TargetType.PARAMETER, TargetType.LOCAL_VARIABLE));
-
- private static final TargetType[] PACKAGE_TARGETS = {TargetType.PACKAGE};
- private static final TargetType[] TYPE_USE_TARGETS = {TargetType.TYPE_USE};
- private static final TargetType[] ANNOTATION_TARGETS = {TargetType.ANNOTATION_TYPE, TargetType.TYPE, TargetType.TYPE_USE};
- private static final TargetType[] TYPE_TARGETS = {TargetType.TYPE, TargetType.TYPE_USE};
- private static final TargetType[] TYPE_PARAMETER_TARGETS = {TargetType.TYPE_PARAMETER, TargetType.TYPE_USE};
- private static final TargetType[] CONSTRUCTOR_TARGETS = {TargetType.CONSTRUCTOR, TargetType.TYPE_USE};
- private static final TargetType[] METHOD_TARGETS = {TargetType.METHOD, TargetType.TYPE_USE};
- private static final TargetType[] FIELD_TARGETS = {TargetType.FIELD, TargetType.TYPE_USE};
- private static final TargetType[] PARAMETER_TARGETS = {TargetType.PARAMETER, TargetType.TYPE_USE};
- private static final TargetType[] LOCAL_VARIABLE_TARGETS ={TargetType.LOCAL_VARIABLE, TargetType.TYPE_USE};
-
private PsiImplUtil() { }
@NotNull
@@ -376,93 +360,14 @@ public class PsiImplUtil {
PsiModifierList modifierList = annotationType.getModifierList();
if (modifierList == null) return null;
PsiAnnotation target = modifierList.findAnnotation(CommonClassNames.JAVA_LANG_ANNOTATION_TARGET);
- if (target == null) return DEFAULT_TARGETS; // if omitted it is applicable to all but Java 8 TYPE_USE/TYPE_PARAMETERS targets
-
- PsiAnnotationMemberValue value = target.findAttributeValue(null);
- if (value instanceof PsiReference) {
- TargetType targetType = translateTargetRef((PsiReference)value);
- if (targetType != null) {
- return Collections.singleton(targetType);
- }
- }
- else if (value instanceof PsiArrayInitializerMemberValue) {
- Set <TargetType> targets = ContainerUtil.newHashSet();
- for (PsiAnnotationMemberValue initializer : ((PsiArrayInitializerMemberValue)value).getInitializers()) {
- if (initializer instanceof PsiReference) {
- TargetType targetType = translateTargetRef((PsiReference)initializer);
- if (targetType != null) {
- targets.add(targetType);
- }
- }
- }
- return targets;
- }
+ if (target == null) return AnnotationTargetUtil.DEFAULT_TARGETS; // if omitted it is applicable to all but Java 8 TYPE_USE/TYPE_PARAMETERS targets
- return null;
- }
-
- @Nullable
- private static TargetType translateTargetRef(PsiReference reference) {
- PsiElement field = reference.resolve();
- if (field instanceof PsiEnumConstant) {
- String name = ((PsiEnumConstant)field).getName();
- try {
- return TargetType.valueOf(name);
- }
- catch (IllegalArgumentException e) {
- LOG.warn("Unknown target: " + name);
- }
- }
- return null;
+ return AnnotationTargetUtil.extractRequiredAnnotationTargets(target.findAttributeValue(null));
}
@NotNull
public static TargetType[] getTargetsForLocation(@Nullable PsiAnnotationOwner owner) {
- if (owner == null) {
- return TargetType.EMPTY_ARRAY;
- }
-
- if (owner instanceof PsiType || owner instanceof PsiTypeElement) {
- return TYPE_USE_TARGETS;
- }
-
- if (owner instanceof PsiTypeParameter) {
- return TYPE_PARAMETER_TARGETS;
- }
-
- if (owner instanceof PsiModifierList) {
- PsiElement element = ((PsiModifierList)owner).getParent();
- if (element instanceof PsiPackageStatement) {
- return PACKAGE_TARGETS;
- }
- if (element instanceof PsiClass) {
- if (((PsiClass)element).isAnnotationType()) {
- return ANNOTATION_TARGETS;
- }
- else {
- return TYPE_TARGETS;
- }
- }
- if (element instanceof PsiMethod) {
- if (((PsiMethod)element).isConstructor()) {
- return CONSTRUCTOR_TARGETS;
- }
- else {
- return METHOD_TARGETS;
- }
- }
- if (element instanceof PsiField) {
- return FIELD_TARGETS;
- }
- if (element instanceof PsiParameter) {
- return PARAMETER_TARGETS;
- }
- if (element instanceof PsiLocalVariable) {
- return LOCAL_VARIABLE_TARGETS;
- }
- }
-
- return TargetType.EMPTY_ARRAY;
+ return AnnotationTargetUtil.getTargetsForLocation(owner);
}
@Nullable
@@ -782,4 +687,33 @@ public class PsiImplUtil {
return element instanceof LeafElement && tokenSet.contains(((LeafElement)element).getElementType());
}
+ public static PsiType buildTypeFromTypeString(@NotNull final String typeName, @NotNull final PsiElement context, @NotNull final PsiFile psiFile) {
+ PsiType resultType;
+ final PsiManager psiManager = psiFile.getManager();
+
+ if (typeName.indexOf('<') != -1 || typeName.indexOf('[') != -1 || typeName.indexOf('.') == -1) {
+ try {
+ return JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory().createTypeFromText(typeName, context);
+ } catch(Exception ex) {} // invalid syntax will produce unresolved class type
+ }
+
+ PsiClass aClass = JavaPsiFacade.getInstance(psiManager.getProject()).findClass(typeName, context.getResolveScope());
+
+ if (aClass == null) {
+ final LightClassReference ref = new LightClassReference(
+ psiManager,
+ PsiNameHelper.getShortClassName(typeName),
+ typeName,
+ PsiSubstitutor.EMPTY,
+ psiFile
+ );
+ resultType = new PsiClassReferenceType(ref, null);
+ } else {
+ PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
+ PsiSubstitutor substitutor = factory.createRawSubstitutor(aClass);
+ resultType = factory.createType(aClass, substitutor);
+ }
+
+ return resultType;
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java
index f1d847cb24c2..e0db7701574d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java
@@ -18,6 +18,7 @@ package com.intellij.psi.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectRootModificationTracker;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
@@ -370,7 +371,12 @@ public class PsiSuperMethodImplUtil {
if (result == null) {
result = new HierarchicalMethodSignatureImpl((MethodSignatureBackedByPsiMethod)method.getSignature(PsiSubstitutor.EMPTY));
}
- return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
+
+ Project project = aClass == null ? method.getProject() : aClass.getProject();
+ // cache Cls method hierarchy until root changed
+ Object dependency = method instanceof PsiCompiledElement ? ProjectRootModificationTracker.getInstance(project) :
+ PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT;
+ return CachedValueProvider.Result.create(result, dependency);
}
};
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java
index d2a66271353d..b356698428d8 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java
@@ -84,7 +84,8 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
- String fqn, shortName;
+ String fqn;
+ String shortName;
if (myShortName != null && name.endsWith(myShortName)) {
shortName = myShortName;
fqn = name.length() == shortName.length()
@@ -338,7 +339,8 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
if (fqn == null) return true; // impossible case, just ignore
if (fqn.length() != signature.length()) return false;
- int p = 0, dot;
+ int p = 0;
+ int dot;
while ((dot = fqn.indexOf('.', p)) >= 0) {
if (!signature.regionMatches(p, fqn, p, dot - p)) {
return false;
@@ -428,24 +430,10 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
List<String> args = new ArrayList<String>();
List<String> throwables = exceptions != null ? new ArrayList<String>() : null;
- final PsiMethodStubImpl stub = new PsiMethodStubImpl(myResult, StringRef.fromString(canonicalMethodName), flags, null);
+ int modifiersMask = packMethodFlags(access, myResult.isInterface());
+ final PsiMethodStubImpl stub = new PsiMethodStubImpl(myResult, StringRef.fromString(canonicalMethodName), flags, signature, args, throwables, desc, modifiersMask);
- final PsiModifierListStub modList = new PsiModifierListStubImpl(stub, packMethodFlags(access, myResult.isInterface()));
-
- String returnType = null;
- boolean parsedViaGenericSignature = false;
- if (signature != null) {
- try {
- returnType = parseMethodViaGenericSignature(signature, stub, args, throwables);
- parsedViaGenericSignature = true;
- }
- catch (ClsFormatException ignored) { }
- }
- if (returnType == null) {
- returnType = parseMethodViaDescription(desc, stub, args);
- }
-
- stub.setReturnType(TypeInfo.fromString(returnType));
+ PsiModifierListStub modList = (PsiModifierListStub)stub.findChildStubByType(JavaStubElementTypes.MODIFIER_LIST);
if (isEnum && isConstructor && signature == null && args.size() >= 2 && JAVA_LANG_STRING.equals(args.get(0)) && "int".equals(args.get(1))) {
// exclude synthetic enum constructor parameters
@@ -454,6 +442,7 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
final boolean isNonStaticInnerClassConstructor =
isConstructor && !(myParent instanceof PsiFileStub) && (myModList.getModifiersMask() & Opcodes.ACC_STATIC) == 0;
+ boolean parsedViaGenericSignature = stub.isParsedViaGenericSignature();
final boolean shouldSkipFirstParamForNonStaticInnerClassConstructor = !parsedViaGenericSignature && isNonStaticInnerClassConstructor;
final PsiParameterListStubImpl parameterList = new PsiParameterListStubImpl(stub);
@@ -502,7 +491,8 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
}
}
- private static String parseMethodViaDescription(final String desc, final PsiMethodStubImpl stub, final List<String> args) {
+ @NotNull
+ public static String parseMethodViaDescription(@NotNull String desc, @NotNull PsiMethodStubImpl stub, @NotNull List<String> args) {
final String returnType = getTypeText(Type.getReturnType(desc));
final Type[] argTypes = Type.getArgumentTypes(desc);
for (Type argType : argTypes) {
@@ -512,10 +502,11 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
return returnType;
}
- private static String parseMethodViaGenericSignature(final String signature,
- final PsiMethodStubImpl stub,
- final List<String> args,
- final List<String> throwables) throws ClsFormatException {
+ @NotNull
+ public static String parseMethodViaGenericSignature(@NotNull String signature,
+ @NotNull PsiMethodStubImpl stub,
+ @NotNull List<String> args,
+ @Nullable List<String> throwables) throws ClsFormatException {
StringCharacterIterator iterator = new StringCharacterIterator(signature);
SignatureParsing.parseTypeParametersDeclaration(iterator, stub);
@@ -651,12 +642,12 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
private int myUsedParamSize = 0;
private int myUsedParamCount = 0;
- private AnnotationParamCollectingVisitor(final PsiMethodStub owner,
- final PsiModifierListStub modList,
+ private AnnotationParamCollectingVisitor(@NotNull PsiMethodStub owner,
+ @NotNull PsiModifierListStub modList,
final int ignoreCount,
final int paramIgnoreCount,
final int paramCount,
- final PsiParameterStubImpl[] paramStubs) {
+ @NotNull PsiParameterStubImpl[] paramStubs) {
super(ASM_API);
myOwner = owner;
myModList = modList;
@@ -758,7 +749,7 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
}
if (value instanceof Double) {
- final double d = ((Double)value).doubleValue();
+ final double d = (Double)value;
if (Double.isInfinite(d)) {
return d > 0 ? DOUBLE_POSITIVE_INF : DOUBLE_NEGATIVE_INF;
}
@@ -769,7 +760,7 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
}
if (value instanceof Float) {
- final float v = ((Float)value).floatValue();
+ final float v = (Float)value;
if (Float.isInfinite(v)) {
return v > 0 ? FLOAT_POSITIVE_INF : FLOAT_NEGATIVE_INF;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java
index 1463355455c2..13487c5514d0 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.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,19 +21,23 @@ package com.intellij.psi.impl.java.stubs.impl;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.impl.cache.TypeInfo;
+import com.intellij.psi.impl.compiled.StubBuildingVisitor;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiMethodStub;
import com.intellij.psi.impl.java.stubs.PsiParameterListStub;
import com.intellij.psi.impl.java.stubs.PsiParameterStub;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
+import com.intellij.util.BitUtil;
+import com.intellij.util.cls.ClsFormatException;
import com.intellij.util.io.StringRef;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.List;
public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodStub {
- private TypeInfo myReturnType;
+ private final TypeInfo myReturnType;
private final byte myFlags;
private final StringRef myName;
private StringRef myDefaultValueText;
@@ -43,15 +47,40 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
private static final int ANNOTATION = 0x04;
private static final int DEPRECATED = 0x08;
private static final int DEPRECATED_ANNOTATION = 0x10;
-
- public PsiMethodStubImpl(StubElement parent, StringRef name, byte flags, StringRef defaultValueText) {
+ private static final int PARSED_VIA_GENERIC_SIGNATURE = 0x20;
+
+ public PsiMethodStubImpl(StubElement parent,
+ StringRef name,
+ byte flags,
+ String signature,
+ @NotNull List<String> args,
+ @Nullable List<String> throwables,
+ String desc,
+ int modifiersMask) {
super(parent, isAnnotationMethod(flags) ? JavaStubElementTypes.ANNOTATION_METHOD : JavaStubElementTypes.METHOD);
- myFlags = flags;
myName = name;
- myDefaultValueText = defaultValueText;
+ myDefaultValueText = null;
+
+ new PsiModifierListStubImpl(this, modifiersMask);
+
+ String returnType = null;
+ boolean parsedViaGenericSignature = false;
+ if (signature != null) {
+ try {
+ returnType = StubBuildingVisitor.parseMethodViaGenericSignature(signature, this, args, throwables);
+ parsedViaGenericSignature = true;
+ }
+ catch (ClsFormatException ignored) { }
+ }
+ if (returnType == null) {
+ returnType = StubBuildingVisitor.parseMethodViaDescription(desc, this, args);
+ }
+
+ myReturnType = TypeInfo.fromString(returnType);
+ myFlags = (byte)(flags | (parsedViaGenericSignature ? PARSED_VIA_GENERIC_SIGNATURE : 0));
}
- public PsiMethodStubImpl(StubElement parent, StringRef name, TypeInfo returnType, byte flags, StringRef defaultValueText) {
+ public PsiMethodStubImpl(StubElement parent, StringRef name, @NotNull TypeInfo returnType, byte flags, StringRef defaultValueText) {
super(parent, isAnnotationMethod(flags) ? JavaStubElementTypes.ANNOTATION_METHOD : JavaStubElementTypes.METHOD);
myReturnType = returnType;
myFlags = flags;
@@ -59,10 +88,6 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
myDefaultValueText = defaultValueText;
}
- public void setReturnType(TypeInfo returnType) {
- myReturnType = returnType;
- }
-
@Override
public boolean isConstructor() {
return (myFlags & CONSTRUCTOR) != 0;
@@ -73,6 +98,9 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
return (myFlags & VARARGS) != 0;
}
+ public boolean isParsedViaGenericSignature() {
+ return BitUtil.isSet(myFlags, PARSED_VIA_GENERIC_SIGNATURE);
+ }
@Override
public boolean isAnnotationMethod() {
return isAnnotationMethod(myFlags);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java
index 58b1e2253d14..b2c934ef9783 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java
@@ -86,12 +86,13 @@ public class JavaResolveCache {
@Nullable
public <T extends PsiExpression> PsiType getType(@NotNull T expr, @NotNull Function<T, PsiType> f) {
- PsiType type = getCachedType(expr);
+ final boolean isOverloadCheck = MethodCandidateInfo.isOverloadCheck();
+ PsiType type = !isOverloadCheck ? getCachedType(expr) : null;
if (type == null) {
final RecursionGuard.StackStamp dStackStamp = PsiDiamondType.ourDiamondGuard.markStack();
final RecursionGuard.StackStamp gStackStamp = PsiResolveHelper.ourGraphGuard.markStack();
type = f.fun(expr);
- if (!dStackStamp.mayCacheNow() || !gStackStamp.mayCacheNow() || !MethodCandidateInfo.ourOverloadGuard.currentStack().isEmpty()) {
+ if (!dStackStamp.mayCacheNow() || !gStackStamp.mayCacheNow() || isOverloadCheck) {
return type;
}
if (type == null) type = TypeConversionUtil.NULL_TYPE;
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 6098199c591c..7d6166a7f95a 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
@@ -349,13 +349,17 @@ public class InferenceSession {
}
public boolean initBounds(PsiTypeParameter... typeParameters) {
+ return initBounds(myContext, typeParameters);
+ }
+
+ public boolean initBounds(PsiElement context, PsiTypeParameter... typeParameters) {
boolean sameMethodCall = false;
for (PsiTypeParameter parameter : typeParameters) {
if (myInferenceVariables.containsKey(parameter)) {
sameMethodCall = true;
continue;
}
- InferenceVariable variable = new InferenceVariable(parameter);
+ InferenceVariable variable = new InferenceVariable(context, parameter);
boolean added = false;
final PsiClassType[] extendsListTypes = parameter.getExtendsListTypes();
for (PsiType classType : extendsListTypes) {
@@ -415,7 +419,7 @@ public class InferenceSession {
for (int i = 0; i < typeParameters.length; i++) {
PsiTypeParameter typeParameter = typeParameters[i];
copy[i] = elementFactory.createTypeParameterFromText("rCopy" + typeParameter.getName(), null);
- initBounds(copy[i]);
+ initBounds(myContext, copy[i]);
subst = subst.put(typeParameter, elementFactory.createType(copy[i]));
}
final PsiType substitutedCapture = PsiUtil.captureToplevelWildcards(subst.substitute(returnType), myContext);
@@ -446,7 +450,7 @@ public class InferenceSession {
}
private static boolean hasPrimitiveWrapperBound(InferenceVariable inferenceVariable) {
- final InferenceBound[] boundTypes = {InferenceBound.UPPER, InferenceBound.LOWER};
+ final InferenceBound[] boundTypes = {InferenceBound.UPPER, InferenceBound.LOWER, InferenceBound.EQ};
for (InferenceBound inferenceBound : boundTypes) {
final List<PsiType> bounds = inferenceVariable.getBounds(inferenceBound);
for (PsiType bound : bounds) {
@@ -701,7 +705,7 @@ public class InferenceSession {
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);
+ final InferenceVariable zVariable = new InferenceVariable(var.getCallContext(), copy);
zVariable.addBound(glb, InferenceBound.UPPER);
if (lub != PsiType.NULL) {
if (!TypeConversionUtil.isAssignable(glb, lub)) {
@@ -1026,7 +1030,7 @@ public class InferenceSession {
boolean varargs) {
final InferenceSession session = new InferenceSession(PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY, m2.getManager(), context);
for (PsiTypeParameter param : PsiUtil.typeParametersIterable(m2)) {
- session.initBounds(param);
+ session.initBounds(context, param);
}
final PsiParameter[] parameters1 = m1.getParameterList().getParameters();
@@ -1250,14 +1254,17 @@ public class InferenceSession {
return myIncorporationPhase.hasCaptureConstraints(Arrays.asList(inferenceVariable));
}
- public void liftBounds(Collection<InferenceVariable> variables) {
+ public void liftBounds(PsiElement context, Collection<InferenceVariable> variables) {
for (InferenceVariable variable : variables) {
final PsiTypeParameter parameter = variable.getParameter();
final InferenceVariable inferenceVariable = getInferenceVariable(parameter);
if (inferenceVariable != null) {
- for (InferenceBound boundType : InferenceBound.values()) {
- for (PsiType bound : variable.getBounds(boundType)) {
- inferenceVariable.addBound(bound, boundType);
+ final PsiElement callContext = inferenceVariable.getCallContext();
+ if (context.equals(callContext) || myContext.equals(callContext)) {
+ for (InferenceBound boundType : InferenceBound.values()) {
+ for (PsiType bound : variable.getBounds(boundType)) {
+ inferenceVariable.addBound(bound, boundType);
+ }
}
}
} else {
@@ -1270,4 +1277,8 @@ public class InferenceSession {
final Boolean erased = call.getUserData(ERASED);
return erased != null && erased.booleanValue();
}
+
+ public PsiElement getContext() {
+ return myContext;
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
index a606e90e8a98..a19961f4c3a9 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
@@ -26,6 +26,8 @@ import java.util.*;
* User: anna
*/
public class InferenceVariable extends LightTypeParameter {
+ private PsiElement myContext;
+
public PsiTypeParameter getParameter() {
return getDelegate();
}
@@ -35,8 +37,9 @@ public class InferenceVariable extends LightTypeParameter {
private PsiType myInstantiation = PsiType.NULL;
- InferenceVariable(PsiTypeParameter parameter) {
+ InferenceVariable(PsiElement context, PsiTypeParameter parameter) {
super(parameter);
+ myContext = context;
}
public PsiType getInstantiation() {
@@ -129,4 +132,8 @@ public class InferenceVariable extends LightTypeParameter {
public String toString() {
return getDelegate().toString();
}
+
+ public PsiElement getCallContext() {
+ return myContext;
+ }
}
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 c33e2c31fa12..82b320ae99f3 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
@@ -110,7 +110,7 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
if (typeParams != null) {
final Set<PsiTypeParameter> oldBounds = ContainerUtil.newHashSet(session.getParamsToInfer());
- final boolean sameMethodCall = session.initBounds(typeParams);
+ final boolean sameMethodCall = session.initBounds(myExpression, typeParams);
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
final HashSet<InferenceVariable> variables = new HashSet<InferenceVariable>();
session.collectDependencies(returnType, variables);
@@ -138,8 +138,8 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
}
final Collection<PsiTypeParameter> params1 = session.getTypeParams();
- final InferenceSession callSession = new InferenceSession(params1.toArray(new PsiTypeParameter[params1.size()]), substitutor, myExpression.getManager(), myExpression);
- callSession.initBounds(params);
+ final InferenceSession callSession = new InferenceSession(params, substitutor, myExpression.getManager(), myExpression);
+ callSession.initBounds(session.getContext(), params1.toArray(new PsiTypeParameter[params1.size()]));
if (method != null) {
final PsiExpression[] args = argumentList.getExpressions();
final PsiParameter[] parameters = method.getParameterList().getParameters();
@@ -163,7 +163,7 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
}
}
}
- session.liftBounds(inferenceVariables);
+ session.liftBounds(myExpression, inferenceVariables);
} else {
return false;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
index 18d0c49e79d4..9516265a8cb5 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
@@ -91,7 +91,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
}
final PsiParameter[] parameters = applicableMember instanceof PsiMethod ? ((PsiMethod)applicableMember).getParameterList().getParameters() : PsiParameter.EMPTY_ARRAY;
if (targetParameters.length == parameters.length + 1) {
- specialCase(session, constraints, substitutor, targetParameters);
+ specialCase(session, constraints, substitutor, targetParameters, true);
for (int i = 1; i < targetParameters.length; i++) {
constraints.add(new TypeCompatibilityConstraint(psiSubstitutor.substitute(parameters[i - 1].getType()), substitutor.substitute(targetParameters[i].getType())));
}
@@ -198,7 +198,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (targetParameters.length == parameters.length + 1 && !method.isVarArgs() &&
PsiPolyExpressionUtil.mentionsTypeParameters(referencedMethodReturnType, ContainerUtil.newHashSet(containingClass.getTypeParameters()))) { //todo specification bug?
- specialCase(session, constraints, substitutor, targetParameters);
+ specialCase(session, constraints, substitutor, targetParameters, false);
}
constraints.add(new TypeCompatibilityConstraint(returnType, psiSubstitutor.substitute(referencedMethodReturnType)));
}
@@ -209,7 +209,8 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
private void specialCase(InferenceSession session,
List<ConstraintFormula> constraints,
PsiSubstitutor substitutor,
- PsiParameter[] targetParameters) {
+ PsiParameter[] targetParameters,
+ boolean ignoreRaw) {
final PsiElement qualifier = myExpression.getQualifier();
PsiType qualifierType = null;
if (qualifier instanceof PsiTypeElement) {
@@ -226,8 +227,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
final PsiElement res = resolveResult.getElement();
if (res instanceof PsiClass) {
PsiClass containingClass = (PsiClass)res;
- final boolean isRawSubst = !myExpression.isConstructor() &&
- PsiUtil.isRawSubstitutor(containingClass, resolveResult.getSubstitutor());
+ final boolean isRawSubst = !ignoreRaw && !myExpression.isConstructor() && PsiUtil.isRawSubstitutor(containingClass, resolveResult.getSubstitutor());
qualifierType = JavaPsiFacade.getElementFactory(res.getProject()).createType(containingClass, isRawSubst ? PsiSubstitutor.EMPTY : resolveResult.getSubstitutor());
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java
index e2af7b08df0d..d4d0f3f0c88d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java
@@ -22,6 +22,7 @@ import com.intellij.lang.LighterASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.DummyHolder;
import com.intellij.psi.impl.source.SourceJavaCodeReference;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
@@ -142,4 +143,41 @@ public class JavaSourceUtil {
TreeUtil.clearCaches(TreeUtil.getFileElement(parenthExpr));
return parenthExpr;
}
+
+ public static void deleteSeparatingComma(@NotNull CompositeElement element, @NotNull ASTNode child) {
+ assert child.getElementType() != JavaTokenType.COMMA : child;
+
+ ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext());
+ if (next != null && next.getElementType() == JavaTokenType.COMMA) {
+ element.deleteChildInternal(next);
+ }
+ else {
+ ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev());
+ if (prev != null && prev.getElementType() == JavaTokenType.COMMA) {
+ element.deleteChildInternal(prev);
+ }
+ }
+ }
+
+ public static void addSeparatingComma(@NotNull CompositeElement element, @NotNull ASTNode child, @NotNull TokenSet listTypes) {
+ assert child.getElementType() != JavaTokenType.COMMA : child;
+
+ scanChildren(element, child, listTypes, true);
+ scanChildren(element, child, listTypes, false);
+ }
+
+ private static void scanChildren(CompositeElement element, ASTNode node, TokenSet listTypes, boolean forward) {
+ ASTNode child = node;
+ while (true) {
+ child = (forward ? child.getTreeNext() : child.getTreePrev());
+ if (child == null || child.getElementType() == JavaTokenType.COMMA) break;
+ if (listTypes.contains(child.getElementType())) {
+ CharTable charTable = SharedImplUtil.findCharTableByTree(element);
+ PsiManager manager = element.getPsi().getManager();
+ TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, charTable, manager);
+ element.addInternal(comma, comma, (forward ? node : child), Boolean.FALSE);
+ break;
+ }
+ }
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationParamListElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationParamListElement.java
index 4953bd2d3804..e1ffc8b91766 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationParamListElement.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationParamListElement.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,8 +19,9 @@ import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.*;
-import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.ChildRoleBase;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
import com.intellij.util.CharTable;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -28,47 +29,29 @@ import org.jetbrains.annotations.NotNull;
/**
* @author ven
*/
-public class AnnotationParamListElement extends PsiCommaSeparatedListImpl implements PsiAnnotationParameterList {
+public class AnnotationParamListElement extends CompositeElement {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.AnnotationParamListElement");
- private volatile PsiNameValuePair[] myCachedMembers = null;
+ private static final TokenSet NAME_VALUE_PAIR_BIT_SET = TokenSet.create(JavaElementType.NAME_VALUE_PAIR);
public AnnotationParamListElement() {
- super(ANNOTATION_PARAMETER_LIST, NAME_VALUE_PAIR_BIT_SET);
- }
-
- @Override
- public void clearCaches() {
- super.clearCaches();
- myCachedMembers = null;
- }
-
- @Override
- @NotNull
- public PsiNameValuePair[] getAttributes() {
- PsiNameValuePair[] cachedMembers = myCachedMembers;
- if (cachedMembers == null) {
- myCachedMembers = cachedMembers = getChildrenAsPsiElements(NAME_VALUE_PAIR_BIT_SET, PsiNameValuePair.ARRAY_FACTORY);
- }
-
- return cachedMembers;
+ super(JavaElementType.ANNOTATION_PARAMETER_LIST);
}
@Override
public int getChildRole(ASTNode child) {
IElementType i = child.getElementType();
- if (i == COMMA) {
+ if (i == JavaTokenType.COMMA) {
return ChildRole.COMMA;
}
- else if (i == LPARENTH) {
+ else if (i == JavaTokenType.LPARENTH) {
return ChildRole.LPARENTH;
}
- else if (i == RPARENTH) {
+ else if (i == JavaTokenType.RPARENTH) {
return ChildRole.RPARENTH;
}
- else if (ANNOTATION_MEMBER_VALUE_BIT_SET.contains(child.getElementType())
- || (i == NAME_VALUE_PAIR && child.getFirstChildNode() != null
- && child.getFirstChildNode().getElementType() == ANNOTATION_ARRAY_INITIALIZER))
- {
+ else if (ElementType.ANNOTATION_MEMBER_VALUE_BIT_SET.contains(i) ||
+ (i == JavaElementType.NAME_VALUE_PAIR && child.getFirstChildNode() != null &&
+ child.getFirstChildNode().getElementType() == JavaElementType.ANNOTATION_ARRAY_INITIALIZER)) {
return ChildRole.ANNOTATION_VALUE;
}
else {
@@ -83,65 +66,69 @@ public class AnnotationParamListElement extends PsiCommaSeparatedListImpl implem
LOG.assertTrue(false);
return null;
case ChildRole.LPARENTH:
- return findChildByType(LPARENTH);
+ return findChildByType(JavaTokenType.LPARENTH);
case ChildRole.RPARENTH:
- return findChildByType(RPARENTH);
- }
- }
-
- public String toString() {
- return "PsiAnnotationParameterList";
- }
-
- @Override
- public void accept(@NotNull PsiElementVisitor visitor) {
- if (visitor instanceof JavaElementVisitor) {
- ((JavaElementVisitor)visitor).visitAnnotationParameterList(this);
- }
- else {
- visitor.visitElement(this);
+ return findChildByType(JavaTokenType.RPARENTH);
}
}
@Override
public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) {
- if (first.getElementType() == NAME_VALUE_PAIR && last.getElementType() == NAME_VALUE_PAIR) {
- final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this);
- ASTNode lparenth = findChildByRole(ChildRole.LPARENTH);
+ if (first.getElementType() == JavaElementType.NAME_VALUE_PAIR && last.getElementType() == JavaElementType.NAME_VALUE_PAIR) {
+ ASTNode lparenth = findChildByType(JavaTokenType.LPARENTH);
if (lparenth == null) {
- LeafElement created = Factory.createSingleLeafElement(LPARENTH, "(", 0, 1, treeCharTab, getManager());
+ CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this);
+ LeafElement created = Factory.createSingleLeafElement(JavaTokenType.LPARENTH, "(", 0, 1, treeCharTab, getManager());
super.addInternal(created, created, getFirstChildNode(), true);
}
- ASTNode rparenth = findChildByRole(ChildRole.RPARENTH);
+
+ ASTNode rparenth = findChildByType(JavaTokenType.RPARENTH);
if (rparenth == null) {
- LeafElement created = Factory.createSingleLeafElement(RPARENTH, ")", 0, 1, treeCharTab, getManager());
+ CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this);
+ LeafElement created = Factory.createSingleLeafElement(JavaTokenType.RPARENTH, ")", 0, 1, treeCharTab, getManager());
super.addInternal(created, created, getLastChildNode(), false);
}
- final ASTNode[] nodes = getChildren(NAME_VALUE_PAIR_BIT_SET);
+ ASTNode[] nodes = getChildren(NAME_VALUE_PAIR_BIT_SET);
if (nodes.length == 1) {
- final ASTNode node = nodes[0];
+ ASTNode node = nodes[0];
if (node instanceof PsiNameValuePair) {
- final PsiNameValuePair pair = (PsiNameValuePair)node;
+ PsiNameValuePair pair = (PsiNameValuePair)node;
if (pair.getName() == null) {
- final String text = pair.getValue().getText();
- try {
- final PsiAnnotation annotation = JavaPsiFacade.getInstance(getProject()).getElementFactory().createAnnotationFromText("@AAA(value = " + text + ")", null);
- replaceChild(node, annotation.getParameterList().getAttributes()[0].getNode());
- }
- catch (IncorrectOperationException e) {
- LOG.error(e);
+ PsiAnnotationMemberValue value = pair.getValue();
+ if (value != null) {
+ try {
+ PsiElementFactory factory = JavaPsiFacade.getInstance(getPsi().getProject()).getElementFactory();
+ PsiAnnotation annotation = factory.createAnnotationFromText("@AAA(value = " + value.getText() + ")", null);
+ replaceChild(node, annotation.getParameterList().getAttributes()[0].getNode());
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
}
}
}
}
if (anchor == null && before != null) {
- anchor = findChildByRole(before.booleanValue() ? ChildRole.RPARENTH : ChildRole.LPARENTH);
+ anchor = findChildByType(before ? JavaTokenType.RPARENTH : JavaTokenType.LPARENTH);
}
+
+ TreeElement firstAdded = super.addInternal(first, last, anchor, before);
+ JavaSourceUtil.addSeparatingComma(this, first, NAME_VALUE_PAIR_BIT_SET);
+ return firstAdded;
}
return super.addInternal(first, last, anchor, before);
}
+
+ @Override
+ public void deleteChildInternal(@NotNull ASTNode child) {
+ if (child.getElementType() == JavaElementType.NAME_VALUE_PAIR) {
+ JavaSourceUtil.deleteSeparatingComma(this, child);
+ }
+
+ super.deleteChildInternal(child);
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java
index 712b32ca6d5b..14d72a92da1c 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,15 @@ import org.jetbrains.annotations.Nullable;
public class ClassElement extends CompositeElement implements Constants {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ClassElement");
+ private static final TokenSet MODIFIERS_TO_REMOVE_IN_INTERFACE_BIT_SET = TokenSet.create(
+ PUBLIC_KEYWORD, ABSTRACT_KEYWORD, STATIC_KEYWORD, FINAL_KEYWORD, NATIVE_KEYWORD);
+ private static final TokenSet MODIFIERS_TO_REMOVE_IN_INTERFACE_BIT_SET_18_METHOD = TokenSet.create(
+ PUBLIC_KEYWORD, ABSTRACT_KEYWORD, FINAL_KEYWORD, NATIVE_KEYWORD);
+ private static final TokenSet MODIFIERS_TO_REMOVE_IN_ENUM_BIT_SET = TokenSet.create(
+ PUBLIC_KEYWORD, FINAL_KEYWORD);
+ private static final TokenSet ENUM_CONSTANT_LIST_ELEMENTS_BIT_SET = TokenSet.create(
+ ENUM_CONSTANT, COMMA, SEMICOLON);
+
public ClassElement(IElementType type) {
super(type);
}
@@ -181,19 +190,8 @@ public class ClassElement extends CompositeElement implements Constants {
@Override
public void deleteChildInternal(@NotNull ASTNode child) {
- if (isEnum()) {
- if (child.getElementType() == ENUM_CONSTANT) {
- ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext());
- if (next != null && next.getElementType() == COMMA) {
- deleteChildInternal(next);
- }
- else {
- ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev());
- if (prev != null && prev.getElementType() == COMMA) {
- deleteChildInternal(prev);
- }
- }
- }
+ if (isEnum() && child.getElementType() == ENUM_CONSTANT) {
+ JavaSourceUtil.deleteSeparatingComma(this, child);
}
if (child.getElementType() == FIELD) {
@@ -233,27 +231,6 @@ public class ClassElement extends CompositeElement implements Constants {
return findChildByRole(ChildRole.AT) != null;
}
- private static final TokenSet MODIFIERS_TO_REMOVE_IN_INTERFACE_BIT_SET = TokenSet.create(
- PUBLIC_KEYWORD, ABSTRACT_KEYWORD,
- STATIC_KEYWORD, FINAL_KEYWORD,
- NATIVE_KEYWORD
- );
-
- private static final TokenSet MODIFIERS_TO_REMOVE_IN_INTERFACE_BIT_SET_18_METHOD = TokenSet.create(
- PUBLIC_KEYWORD, ABSTRACT_KEYWORD,
- FINAL_KEYWORD,
- NATIVE_KEYWORD
- );
-
- private static final TokenSet MODIFIERS_TO_REMOVE_IN_ENUM_BIT_SET = TokenSet.create(
- PUBLIC_KEYWORD, FINAL_KEYWORD
- );
-
- private static final TokenSet ENUM_CONSTANT_LIST_ELEMENTS_BIT_SET = TokenSet.create(
- ENUM_CONSTANT, COMMA, SEMICOLON
- );
-
-
@Override
public ASTNode findChildByRole(int role) {
assert ChildRole.isUnique(role);
@@ -266,10 +243,7 @@ public class ClassElement extends CompositeElement implements Constants {
return PsiImplUtil.findDocComment(this);
case ChildRole.ENUM_CONSTANT_LIST_DELIMITER:
- if (!isEnum()) {
- return null;
- }
- return findEnumConstantListDelimiter();
+ return isEnum() ? findEnumConstantListDelimiter() : null;
case ChildRole.MODIFIER_LIST:
return findChildByType(MODIFIER_LIST);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterListElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterListElement.java
index a5e32e9ce95b..20d504d8dbae 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterListElement.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterListElement.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,18 +18,21 @@ package com.intellij.psi.impl.source.tree.java;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.Constants;
-import com.intellij.psi.impl.source.tree.*;
+import com.intellij.psi.impl.source.tree.ChildRole;
+import com.intellij.psi.impl.source.tree.CompositeElement;
+import com.intellij.psi.impl.source.tree.JavaSourceUtil;
+import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.tree.IElementType;
-import com.intellij.util.CharTable;
+import com.intellij.psi.tree.TokenSet;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ParameterListElement extends CompositeElement implements Constants {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ParameterListElement");
+ private static final TokenSet PARAMETER_SET = TokenSet.create(PARAMETER);
public ParameterListElement() {
super(PARAMETER_LIST);
@@ -49,23 +52,7 @@ public class ParameterListElement extends CompositeElement implements Constants
}
TreeElement firstAdded = super.addInternal(first, last, anchor, before);
if (first == last && first.getElementType() == PARAMETER) {
- final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this);
- for (ASTNode child = ((ASTNode)first).getTreeNext(); child != null; child = child.getTreeNext()) {
- if (child.getElementType() == COMMA) break;
- if (child.getElementType() == PARAMETER) {
- TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, treeCharTab, getManager());
- super.addInternal(comma, comma, first, Boolean.FALSE);
- break;
- }
- }
- for (ASTNode child = ((ASTNode)first).getTreePrev(); child != null; child = child.getTreePrev()) {
- if (child.getElementType() == COMMA) break;
- if (child.getElementType() == PARAMETER) {
- TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, treeCharTab, getManager());
- super.addInternal(comma, comma, child, Boolean.FALSE);
- break;
- }
- }
+ JavaSourceUtil.addSeparatingComma(this, first, PARAMETER_SET);
}
//todo[max] hack?
@@ -83,16 +70,7 @@ public class ParameterListElement extends CompositeElement implements Constants
final TreeElement oldLastNodeInsideParens = getLastNodeInsideParens();
final TreeElement oldFirstNodeInsideParens = getFirstNodeInsideParens();
if (child.getElementType() == PARAMETER) {
- ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext());
- if (next != null && next.getElementType() == COMMA) {
- deleteChildInternal(next);
- }
- else {
- ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev());
- if (prev != null && prev.getElementType() == COMMA) {
- deleteChildInternal(prev);
- }
- }
+ JavaSourceUtil.deleteSeparatingComma(this, child);
}
super.deleteChildInternal(child);
@@ -135,20 +113,12 @@ public class ParameterListElement extends CompositeElement implements Constants
return null;
case ChildRole.LPARENTH:
- if (getFirstChildNode().getElementType() == LPARENTH) {
- return getFirstChildNode();
- }
- else {
- return null;
- }
+ TreeElement firstNode = getFirstChildNode();
+ return firstNode.getElementType() == LPARENTH ? firstNode : null;
case ChildRole.RPARENTH:
- if (getLastChildNode().getElementType() == RPARENTH) {
- return getLastChildNode();
- }
- else {
- return null;
- }
+ TreeElement lastNode = getLastChildNode();
+ return lastNode.getElementType() == RPARENTH ? lastNode : null;
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationParamListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationParamListImpl.java
index 5a3ccb23e420..0923d7cdd675 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationParamListImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationParamListImpl.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,20 +16,20 @@
package com.intellij.psi.impl.source.tree.java;
import com.intellij.lang.ASTNode;
+import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.PsiAnnotationParameterList;
+import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiNameValuePair;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiAnnotationParameterListStub;
import com.intellij.psi.impl.source.JavaStubPsiElement;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Avdeev
- * Date: 7/27/12
+ * @since 27.07.2012
*/
-public class PsiAnnotationParamListImpl extends JavaStubPsiElement<PsiAnnotationParameterListStub> implements
- PsiAnnotationParameterList {
+public class PsiAnnotationParamListImpl extends JavaStubPsiElement<PsiAnnotationParameterListStub> implements PsiAnnotationParameterList {
public PsiAnnotationParamListImpl(@NotNull PsiAnnotationParameterListStub stub) {
super(stub, JavaStubElementTypes.ANNOTATION_PARAMETER_LIST);
}
@@ -44,8 +44,18 @@ public class PsiAnnotationParamListImpl extends JavaStubPsiElement<PsiAnnotation
return getStubOrPsiChildren(JavaStubElementTypes.NAME_VALUE_PAIR, PsiNameValuePair.ARRAY_FACTORY);
}
- @NonNls
- public String toString(){
- return "PsiAnnotationParameterList:" + getText();
+ @Override
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JavaElementVisitor) {
+ ((JavaElementVisitor)visitor).visitAnnotationParameterList(this);
+ }
+ else {
+ visitor.visitElement(this);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "PsiAnnotationParameterList";
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java
index dd64ed7e41fb..b03766f54d55 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.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,68 +17,84 @@ package com.intellij.psi.impl.source.tree.java;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.psi.JavaElementVisitor;
-import com.intellij.psi.PsiAnnotationMemberValue;
-import com.intellij.psi.PsiArrayInitializerMemberValue;
-import com.intellij.psi.PsiElementVisitor;
-import com.intellij.psi.impl.source.tree.ChildRole;
-import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.tree.ChildRoleBase;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
/**
* @author ven
*/
-public class PsiArrayInitializerMemberValueImpl extends PsiCommaSeparatedListImpl implements PsiArrayInitializerMemberValue {
- private static final Logger LOG = Logger.getInstance("com.intellij.psi.impl.source.tree.java.PsiArrayInitializerMemberValueImpl");
+public class PsiArrayInitializerMemberValueImpl extends CompositePsiElement implements PsiArrayInitializerMemberValue {
+ private static final Logger LOG = Logger.getInstance(PsiArrayInitializerMemberValueImpl.class);
+ private static final TokenSet MEMBER_SET = ElementType.ANNOTATION_MEMBER_VALUE_BIT_SET;
+
public PsiArrayInitializerMemberValueImpl() {
- super(ANNOTATION_ARRAY_INITIALIZER, ANNOTATION_MEMBER_VALUE_BIT_SET);
+ super(JavaElementType.ANNOTATION_ARRAY_INITIALIZER);
}
@Override
@NotNull
public PsiAnnotationMemberValue[] getInitializers() {
- return getChildrenAsPsiElements(ANNOTATION_MEMBER_VALUE_BIT_SET, PsiAnnotationMemberValue.ARRAY_FACTORY);
+ return getChildrenAsPsiElements(MEMBER_SET, PsiAnnotationMemberValue.ARRAY_FACTORY);
}
@Override
public ASTNode findChildByRole(int role) {
LOG.assertTrue(ChildRole.isUnique(role));
- switch(role){
+
+ switch (role) {
default:
return null;
case ChildRole.LBRACE:
- return findChildByType(LBRACE);
+ return findChildByType(JavaTokenType.LBRACE);
case ChildRole.RBRACE:
- return findChildByType(RBRACE);
+ return findChildByType(JavaTokenType.RBRACE);
}
}
@Override
public int getChildRole(ASTNode child) {
LOG.assertTrue(child.getTreeParent() == this);
+
IElementType i = child.getElementType();
- if (i == COMMA) {
+ if (i == JavaTokenType.COMMA) {
return ChildRole.COMMA;
}
- else if (i == LBRACE) {
+ else if (i == JavaTokenType.LBRACE) {
return ChildRole.LBRACE;
}
- else if (i == RBRACE) {
+ else if (i == JavaTokenType.RBRACE) {
return ChildRole.RBRACE;
}
- else {
- if (ANNOTATION_MEMBER_VALUE_BIT_SET.contains(child.getElementType())) {
- return ChildRole.ANNOTATION_VALUE;
- }
- return ChildRoleBase.NONE;
+ else if (MEMBER_SET.contains(child.getElementType())) {
+ return ChildRole.ANNOTATION_VALUE;
}
+ return ChildRoleBase.NONE;
}
- public String toString(){
- return "PsiArrayInitializerMemberValue:" + getText();
+ @Override
+ public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) {
+ if (MEMBER_SET.contains(first.getElementType()) && MEMBER_SET.contains(last.getElementType())) {
+ TreeElement firstAdded = super.addInternal(first, last, anchor, before);
+ JavaSourceUtil.addSeparatingComma(this, first, MEMBER_SET);
+ return firstAdded;
+ }
+
+ return super.addInternal(first, last, anchor, before);
+ }
+
+ @Override
+ public void deleteChildInternal(@NotNull ASTNode child) {
+ if (MEMBER_SET.contains(child.getElementType())) {
+ JavaSourceUtil.deleteSeparatingComma(this, child);
+ }
+
+ super.deleteChildInternal(child);
}
@Override
@@ -90,4 +106,9 @@ public class PsiArrayInitializerMemberValueImpl extends PsiCommaSeparatedListImp
visitor.visitElement(this);
}
}
+
+ @Override
+ public String toString() {
+ return "PsiArrayInitializerMemberValue:" + getText();
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCommaSeparatedListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCommaSeparatedListImpl.java
deleted file mode 100644
index 475542fdc868..000000000000
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCommaSeparatedListImpl.java
+++ /dev/null
@@ -1,85 +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.psi.impl.source.tree.java;
-
-import com.intellij.lang.ASTNode;
-import com.intellij.psi.impl.PsiImplUtil;
-import com.intellij.psi.impl.source.Constants;
-import com.intellij.psi.impl.source.tree.*;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.tree.TokenSet;
-import com.intellij.util.CharTable;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Adds or removes comma
- *
- * @author ven
- */
-public abstract class PsiCommaSeparatedListImpl extends CompositePsiElement implements Constants {
- private final TokenSet myTypesOfElements;
-
- protected PsiCommaSeparatedListImpl(IElementType type, final TokenSet typeOfElements) {
- super(type);
- myTypesOfElements = typeOfElements;
- }
-
- @Override
- public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) {
- if (myTypesOfElements.contains(first.getElementType()) && myTypesOfElements.contains(last.getElementType())) {
- final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this);
- final TreeElement firstAdded = super.addInternal(first, last, anchor, before);
- for (ASTNode child = ((ASTNode)first).getTreeNext(); child != null; child = child.getTreeNext()) {
- if (child.getElementType() == COMMA) break;
- if (myTypesOfElements.contains(child.getElementType())) {
- TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, treeCharTab, getManager());
- super.addInternal(comma, comma, first, Boolean.FALSE);
- break;
- }
- }
-
- for (ASTNode child = ((ASTNode)first).getTreePrev(); child != null; child = child.getTreePrev()) {
- if (child.getElementType() == COMMA) break;
- if (myTypesOfElements.contains(child.getElementType())) {
- TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, treeCharTab, getManager());
- super.addInternal(comma, comma, child, Boolean.FALSE);
- break;
- }
- }
- return firstAdded;
- }
-
- return super.addInternal(first, last, anchor, before);
- }
-
- @Override
- public void deleteChildInternal(@NotNull ASTNode child) {
- if (myTypesOfElements.contains(child.getElementType())) {
- ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext());
- if (next != null && next.getElementType() == COMMA) {
- deleteChildInternal(next);
- }
- else {
- ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev());
- if (prev != null && prev.getElementType() == COMMA) {
- deleteChildInternal(prev);
- }
- }
- }
- super.deleteChildInternal(child);
- }
-}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java
index ae45273b57f1..98df0baa4134 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.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,6 @@ package com.intellij.psi.impl.source.tree.java;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
-import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.tree.IElementType;
@@ -123,7 +122,8 @@ public class PsiExpressionListImpl extends CompositePsiElement implements PsiExp
}
TreeElement firstAdded = super.addInternal(first, last, anchor, before);
if (ElementType.EXPRESSION_BIT_SET.contains(first.getElementType())) {
- ASTNode element = first;
+ JavaSourceUtil.addSeparatingComma(this, first, ElementType.EXPRESSION_BIT_SET);
+ /*ASTNode element = first;
for (ASTNode child = element.getTreeNext(); child != null; child = child.getTreeNext()) {
if (child.getElementType() == JavaTokenType.COMMA) break;
if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
@@ -140,7 +140,7 @@ public class PsiExpressionListImpl extends CompositePsiElement implements PsiExp
super.addInternal(comma, comma, child, Boolean.FALSE);
break;
}
- }
+ }*/
}
return firstAdded;
}
@@ -148,17 +148,9 @@ public class PsiExpressionListImpl extends CompositePsiElement implements PsiExp
@Override
public void deleteChildInternal(@NotNull ASTNode child) {
if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
- ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext());
- if (next != null && next.getElementType() == JavaTokenType.COMMA) {
- deleteChildInternal(next);
- }
- else {
- ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev());
- if (prev != null && prev.getElementType() == JavaTokenType.COMMA) {
- deleteChildInternal(prev);
- }
- }
+ JavaSourceUtil.deleteSeparatingComma(this, child);
}
+
super.deleteChildInternal(child);
}
@@ -172,6 +164,7 @@ public class PsiExpressionListImpl extends CompositePsiElement implements PsiExp
}
}
+ @Override
public String toString() {
return "PsiExpressionList";
}
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 95171ba30bc9..32ed1aac5c91 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
@@ -25,6 +25,7 @@ import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.impl.source.resolve.ResolveCache;
import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
+import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.FileElement;
import com.intellij.psi.impl.source.tree.JavaElementType;
@@ -39,13 +40,12 @@ import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.*;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase implements PsiMethodReferenceExpression {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiMethodReferenceExpressionImpl");
@@ -153,7 +153,8 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
if (arrayClass == containingClass) {
final PsiType componentType = qualifierResolveResult.getSubstitutor().substitute(arrayClass.getTypeParameters()[0]);
LOG.assertTrue(componentType != null, qualifierResolveResult.getSubstitutor());
- methods = new PsiMethod[] {factory.createMethodFromText("public " + componentType.createArrayType().getCanonicalText() + " __array__(int i) {return null;}", this)};
+ //15.13.1 A method reference expression of the form ArrayType :: new is always exact.
+ return factory.createMethodFromText("public " + componentType.createArrayType().getCanonicalText() + " __array__(int i) {return null;}", this);
} else {
methods = containingClass.getConstructors();
}
@@ -172,25 +173,38 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
if (psiMethod.getTypeParameters().length > 0) {
final PsiReferenceParameterList parameterList = getParameterList();
return parameterList != null && parameterList.getTypeParameterElements().length > 0 ? psiMethod : null;
+ } else {
+ final PsiSubstitutor classSubstitutor = TypeConversionUtil.getClassSubstitutor(psiMethod.getContainingClass(), containingClass, PsiSubstitutor.EMPTY);
+ final Set<PsiType> signature = new HashSet<PsiType>(Arrays.asList(psiMethod.getSignature(PsiSubstitutor.EMPTY).getParameterTypes()));
+ signature.add(psiMethod.getReturnType());
+ boolean free = true;
+ for (PsiType type : signature) {
+ if (classSubstitutor != null) {
+ type = classSubstitutor.substitute(type);
+ }
+ if (type != null && PsiPolyExpressionUtil.mentionsTypeParameters(type, ContainerUtil.newHashSet(containingClass.getTypeParameters()))) {
+ free = false;
+ break;
+ }
+ }
+ if (free) return psiMethod;
}
}
- if (containingClass.isPhysical() && containingClass.hasTypeParameters()) {
+ if (containingClass.hasTypeParameters()) {
final PsiElement qualifier = getQualifier();
+ PsiJavaCodeReferenceElement referenceElement = null;
if (qualifier instanceof PsiTypeElement) {
- final PsiJavaCodeReferenceElement referenceElement = ((PsiTypeElement)qualifier).getInnermostComponentReferenceElement();
- if (referenceElement != null) {
- final PsiReferenceParameterList parameterList = referenceElement.getParameterList();
- if (parameterList == null || parameterList.getTypeParameterElements().length == 0) {
- return null;
- }
- }
+ referenceElement = ((PsiTypeElement)qualifier).getInnermostComponentReferenceElement();
} else if (qualifier instanceof PsiReferenceExpression) {
final PsiReferenceExpression expression = (PsiReferenceExpression)qualifier;
if (qualifierResolveResult.isReferenceTypeQualified()) {
- final PsiReferenceParameterList parameterList = expression.getParameterList();
- if (parameterList == null || parameterList.getTypeParameterElements().length == 0) {
- return null;
- }
+ referenceElement = expression;
+ }
+ }
+ if (referenceElement != null) {
+ final PsiReferenceParameterList parameterList = referenceElement.getParameterList();
+ if (parameterList == null || parameterList.getTypeParameterElements().length == 0) {
+ return null;
}
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java
index e85e81cb4bd8..743bd36abf5f 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.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.impl.PsiImplUtil;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
import com.intellij.util.CharTable;
import org.jetbrains.annotations.NotNull;
@@ -30,6 +31,7 @@ import org.jetbrains.annotations.NotNull;
*/
public class PsiReferenceParameterListImpl extends CompositePsiElement implements PsiReferenceParameterList {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiReferenceParameterListImpl");
+ private static final TokenSet TYPE_SET = TokenSet.create(JavaElementType.TYPE);
public PsiReferenceParameterListImpl() {
super(JavaElementType.REFERENCE_PARAMETER_LIST);
@@ -124,23 +126,8 @@ public class PsiReferenceParameterListImpl extends CompositePsiElement implement
final TreeElement firstAdded = super.addInternal(first, last, anchor, before);
- if (first == last && first.getElementType() == JavaElementType.TYPE){
- for(ASTNode child = first.getTreeNext(); child != null; child = child.getTreeNext()){
- if (child.getElementType() == JavaTokenType.COMMA) break;
- if (child.getElementType() == JavaElementType.TYPE){
- TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, treeCharTab, getManager());
- super.addInternal(comma, comma, first, Boolean.FALSE);
- break;
- }
- }
- for(ASTNode child = first.getTreePrev(); child != null; child = child.getTreePrev()){
- if (child.getElementType() == JavaTokenType.COMMA) break;
- if (child.getElementType() == JavaElementType.TYPE){
- TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, treeCharTab, getManager());
- super.addInternal(comma, comma, child, Boolean.FALSE);
- break;
- }
- }
+ if (first == last && first.getElementType() == JavaElementType.TYPE) {
+ JavaSourceUtil.addSeparatingComma(this, first, TYPE_SET);
}
return firstAdded;
@@ -148,17 +135,8 @@ public class PsiReferenceParameterListImpl extends CompositePsiElement implement
@Override
public void deleteChildInternal(@NotNull ASTNode child) {
- if (child.getElementType() == JavaElementType.TYPE){
- ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext());
- if (next != null && next.getElementType() == JavaTokenType.COMMA){
- deleteChildInternal(next);
- }
- else{
- ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev());
- if (prev != null && prev.getElementType() == JavaTokenType.COMMA){
- deleteChildInternal(prev);
- }
- }
+ if (child.getElementType() == JavaElementType.TYPE) {
+ JavaSourceUtil.deleteSeparatingComma(this, child);
}
super.deleteChildInternal(child);
@@ -186,6 +164,7 @@ public class PsiReferenceParameterListImpl extends CompositePsiElement implement
}
}
+ @Override
public String toString() {
return "PsiReferenceParameterList";
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java
index 43d9d80c5742..2a3bdbaa2f4e 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
import com.intellij.util.CharTable;
import org.jetbrains.annotations.NotNull;
@@ -30,6 +31,7 @@ import org.jetbrains.annotations.NotNull;
*/
public class TypeParameterListElement extends CompositeElement {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.TypeParameterListElement");
+ private static final TokenSet TYPE_PARAMETER_SET = TokenSet.create(JavaElementType.TYPE_PARAMETER);
public TypeParameterListElement() {
super(JavaElementType.TYPE_PARAMETER_LIST);
@@ -82,25 +84,9 @@ public class TypeParameterListElement extends CompositeElement {
}
}
- final TreeElement firstAdded = super.addInternal(first, last, anchor, before);
-
+ TreeElement firstAdded = super.addInternal(first, last, anchor, before);
if (first == last && first.getElementType() == JavaElementType.TYPE_PARAMETER) {
- for(ASTNode child = first.getTreeNext(); child != null; child = child.getTreeNext()){
- if (child.getElementType() == JavaTokenType.COMMA) break;
- if (child.getElementType() == JavaElementType.TYPE_PARAMETER){
- final TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, treeCharTab, getManager());
- super.addInternal(comma, comma, first, Boolean.FALSE);
- break;
- }
- }
- for(ASTNode child = first.getTreePrev(); child != null; child = child.getTreePrev()){
- if (child.getElementType() == JavaTokenType.COMMA) break;
- if (child.getElementType() == JavaElementType.TYPE_PARAMETER){
- final TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, treeCharTab, getManager());
- super.addInternal(comma, comma, child, Boolean.FALSE);
- break;
- }
- }
+ JavaSourceUtil.addSeparatingComma(this, first, TYPE_PARAMETER_SET);
}
return firstAdded;
}
@@ -108,18 +94,11 @@ public class TypeParameterListElement extends CompositeElement {
@Override
public void deleteChildInternal(@NotNull final ASTNode child) {
if (child.getElementType() == JavaElementType.TYPE_PARAMETER){
- final ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext());
- if (next != null && next.getElementType() == JavaTokenType.COMMA){
- deleteChildInternal(next);
- }
- else{
- final ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev());
- if (prev != null && prev.getElementType() == JavaTokenType.COMMA){
- deleteChildInternal(prev);
- }
- }
+ JavaSourceUtil.deleteSeparatingComma(this, child);
}
+
super.deleteChildInternal(child);
+
if (child.getElementType() == JavaElementType.TYPE_PARAMETER) {
final ASTNode lt = findChildByRole(ChildRole.LT_IN_TYPE_LIST);
final ASTNode next = PsiImplUtil.skipWhitespaceAndComments(lt.getTreeNext());
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
index 59083c625f82..3d9ea08125a8 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
@@ -316,7 +316,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
// prefer derived class
signatures.put(signature, info);
- } else {
+ }
+ else {
final PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(myArgumentsList, PsiMethodCallExpression.class);
if (methodCallExpression != null) {
final PsiReferenceExpression expression = methodCallExpression.getMethodExpression();
@@ -324,14 +325,16 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
PsiClass currentClass;
if (qualifierExpression != null) {
currentClass = PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType());
- } else {
+ }
+ else {
currentClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
}
- if (currentClass != null && InheritanceUtil.isInheritorOrSelf(currentClass, class1, true) && InheritanceUtil.isInheritorOrSelf(currentClass, existingClass, true)) {
- final PsiSubstitutor eSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(existingClass, currentClass, PsiSubstitutor.EMPTY);
- final PsiSubstitutor cSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(class1, currentClass, PsiSubstitutor.EMPTY);
- if (MethodSignatureUtil.areSignaturesEqual(existingMethod.getSignature(eSubstitutor), method.getSignature(cSubstitutor))) {
+ if (currentClass != null) {
+ final PsiSubstitutor eSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(existingClass, currentClass, PsiSubstitutor.EMPTY, null);
+ final PsiSubstitutor cSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(class1, currentClass, PsiSubstitutor.EMPTY, null);
+ if (eSubstitutor != null && cSubstitutor != null &&
+ MethodSignatureUtil.areSignaturesEqual(existingMethod.getSignature(eSubstitutor), method.getSignature(cSubstitutor))) {
final PsiType returnType = eSubstitutor.substitute(existingMethod.getReturnType());
final PsiType returnType1 = cSubstitutor.substitute(method.getReturnType());
if (returnType != null && returnType1 != null && !returnType1.equals(returnType)) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java
index 2b36a9c49b47..c12972d354c7 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java
@@ -83,7 +83,7 @@ public class MethodCandidatesProcessor extends MethodsProcessor{
public PsiType[] getArgumentTypes() {
if (myExpressionTypes == null && argumentList != null) {
final PsiType[] expressionTypes = getExpressionTypes(argumentList);
- if (!MethodCandidateInfo.ourOverloadGuard.currentStack().isEmpty()) {
+ if (MethodCandidateInfo.isOverloadCheck()) {
return expressionTypes;
}
myExpressionTypes = expressionTypes;
diff --git a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java
index c1afbee6ada4..669080107623 100644
--- a/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java
+++ b/java/java-structure-view/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java
@@ -51,12 +51,12 @@ public class PsiMethodTreeElement extends JavaClassTreeElementBase<PsiMethod> im
final PsiMethod element = getElement();
if (element == null || element instanceof SyntheticElement) return result;
- final TextRange range = element.getTextRange();
- if (range == null) return result;
-
final PsiFile psiFile = element.getContainingFile();
if (psiFile == null || psiFile instanceof PsiCompiledElement) return result;
+ final TextRange range = element.getTextRange();
+ if (range == null) return result;
+
final String fileText = psiFile.getText();
if (fileText == null) return result;
diff --git a/java/java-tests/testData/codeInsight/clsHighlighting/IDEA127714.java b/java/java-tests/testData/codeInsight/clsHighlighting/IDEA127714.java
new file mode 100644
index 000000000000..08713f898f15
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/clsHighlighting/IDEA127714.java
@@ -0,0 +1,9 @@
+import a.A;
+
+class IDEA127714 {
+ {
+ A<E, String> strings = new A<>(E.class);
+ }
+}
+
+enum E {} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/clsHighlighting/libs/IDEA127714.jar b/java/java-tests/testData/codeInsight/clsHighlighting/libs/IDEA127714.jar
new file mode 100644
index 000000000000..915d3a074810
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/clsHighlighting/libs/IDEA127714.jar
Binary files differ
diff --git a/java/java-tests/testData/codeInsight/completeStatement/AlreadyCompleteCatch.java b/java/java-tests/testData/codeInsight/completeStatement/AlreadyCompleteCatch.java
new file mode 100644
index 000000000000..d8ea6191cef8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completeStatement/AlreadyCompleteCatch.java
@@ -0,0 +1,12 @@
+
+class Foo {
+ {
+ try
+ {
+
+ } catch (Ex<caret>ception e)
+ {
+
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completeStatement/AlreadyCompleteCatch_after.java b/java/java-tests/testData/codeInsight/completeStatement/AlreadyCompleteCatch_after.java
new file mode 100644
index 000000000000..f4874b45962e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completeStatement/AlreadyCompleteCatch_after.java
@@ -0,0 +1,12 @@
+
+class Foo {
+ {
+ try
+ {
+
+ } catch (Exception e)
+ {
+ <caret>
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normal/MulticaretCompletionFromNonPrimaryCaret.java b/java/java-tests/testData/codeInsight/completion/normal/MulticaretCompletionFromNonPrimaryCaret.java
new file mode 100644
index 000000000000..077ff80bd5c7
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/MulticaretCompletionFromNonPrimaryCaret.java
@@ -0,0 +1,4 @@
+class Foo {{
+ System.<caret>
+ System.<caret>
+}}
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/DontSuggestWildcardGenerics-out.java b/java/java-tests/testData/codeInsight/completion/smartType/DontSuggestWildcardGenerics-out.java
new file mode 100644
index 000000000000..41f3d57525a2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/smartType/DontSuggestWildcardGenerics-out.java
@@ -0,0 +1,16 @@
+class Main {
+ void foo(List<? extends Number> list) {
+ list.forEach(new Consumer<Number>() {
+ @Override
+ public void consume(Number number) {
+ <caret>
+ }
+ });
+ }
+}
+
+class List<T> {
+ void forEach(Consumer<? super T> consumer);
+}
+
+interface Consumer<T> { void consume(T t); } \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/DontSuggestWildcardGenerics.java b/java/java-tests/testData/codeInsight/completion/smartType/DontSuggestWildcardGenerics.java
new file mode 100644
index 000000000000..b1d18904a6fb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/smartType/DontSuggestWildcardGenerics.java
@@ -0,0 +1,11 @@
+class Main {
+ void foo(List<? extends Number> list) {
+ list.forEach(new <caret>);
+ }
+}
+
+class List<T> {
+ void forEach(Consumer<? super T> consumer);
+}
+
+interface Consumer<T> { void consume(T t); } \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferFieldsToConstants.java b/java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferFieldsToConstants.java
new file mode 100644
index 000000000000..2b47bb58a498
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/smartTypeSorting/PreferFieldsToConstants.java
@@ -0,0 +1,17 @@
+public class Foo {
+
+ private LocalDate dateField;
+
+ void foo(LocalDate date) {
+
+ }
+
+ void bar() {
+ foo(<caret>)
+ }
+}
+
+class LocalDate {
+ public static final LocalDate MAX;
+ public static final LocalDate MIN;
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/PolymorphicTypeCast.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/PolymorphicTypeCast.java
index 8be16fc1db85..8ba3ea4f8037 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/PolymorphicTypeCast.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/PolymorphicTypeCast.java
@@ -94,4 +94,96 @@ class C {
void asLongs(Integer i) {
long l = (long) i;
}
+
+ void foo(Object o) {}
+ public void cast2(Byte operand) {
+ foo((<warning descr="Casting 'operand' to 'byte' is redundant">byte</warning>)operand);
+ foo((short)operand);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Byte' to 'char'">(char)operand</error>);
+ foo((int)operand);
+ foo((long)operand);
+ foo((float)operand);
+ foo((double)operand);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Byte' to 'boolean'">(boolean)operand</error>);
+ }
+ public void cast2(Short operand) {
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Short' to 'byte'">(byte)operand</error>);
+ foo((<warning descr="Casting 'operand' to 'short' is redundant">short</warning>)operand);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Short' to 'char'">(char)operand</error>);
+ foo((int)operand);
+ foo((long)operand);
+ foo((float)operand);
+ foo((double)operand);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Short' to 'boolean'">(boolean)operand</error>);
+ }
+ public void cast2(Character operand) {
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Character' to 'byte'">(byte)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Character' to 'short'">(short)operand</error>);
+ foo((<warning descr="Casting 'operand' to 'char' is redundant">char</warning>)operand);
+ foo((int)operand);
+ foo((long)operand);
+ foo((float)operand);
+ foo((double)operand);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Character' to 'boolean'">(boolean)operand</error>);
+ }
+ public void cast2(Integer operand) {
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Integer' to 'byte'">(byte)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Integer' to 'short'">(short)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Integer' to 'char'">(char)operand</error>);
+ foo((<warning descr="Casting 'operand' to 'int' is redundant">int</warning>)operand);
+ foo((long)operand);
+ foo((float)operand);
+ foo((double)operand);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Integer' to 'boolean'">(boolean)operand</error>);
+ }
+ public void cast2(Long operand) {
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Long' to 'byte'">(byte)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Long' to 'short'">(short)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Long' to 'char'">(char)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Long' to 'int'">(int)operand</error>);
+ foo((<warning descr="Casting 'operand' to 'long' is redundant">long</warning>)operand);
+ foo((float)operand);
+ foo((double)operand);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Long' to 'boolean'">(boolean)operand</error>);
+ }
+ public void cast2(Float operand) {
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Float' to 'byte'">(byte)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Float' to 'short'">(short)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Float' to 'char'">(char)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Float' to 'int'">(int)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Float' to 'long'">(long)operand</error>);
+ foo((<warning descr="Casting 'operand' to 'float' is redundant">float</warning>)operand);
+ foo((double)operand);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Float' to 'boolean'">(boolean)operand</error>);
+ }
+ public void cast2(Double operand) {
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Double' to 'byte'">(byte)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Double' to 'short'">(short)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Double' to 'char'">(char)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Double' to 'int'">(int)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Double' to 'long'">(long)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Double' to 'float'">(float)operand</error>);
+ foo((<warning descr="Casting 'operand' to 'double' is redundant">double</warning>)operand);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Double' to 'boolean'">(boolean)operand</error>);
+ }
+ public void cast2(Boolean operand) {
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Boolean' to 'byte'">(byte)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Boolean' to 'short'">(short)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Boolean' to 'char'">(char)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Boolean' to 'int'">(int)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Boolean' to 'long'">(long)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Boolean' to 'float'">(float)operand</error>);
+ foo(<error descr="Inconvertible types; cannot cast 'java.lang.Boolean' to 'double'">(double)operand</error>);
+ foo((<warning descr="Casting 'operand' to 'boolean' is redundant">boolean</warning>)operand);
+ }
+ public void cast2(Object operand) {
+ foo((<warning descr="Casting 'operand' to 'byte' is redundant">byte</warning>)operand);
+ foo((<warning descr="Casting 'operand' to 'short' is redundant">short</warning>)operand);
+ foo((<warning descr="Casting 'operand' to 'char' is redundant">char</warning>)operand);
+ foo((<warning descr="Casting 'operand' to 'int' is redundant">int</warning>)operand);
+ foo((<warning descr="Casting 'operand' to 'long' is redundant">long</warning>)operand);
+ foo((<warning descr="Casting 'operand' to 'float' is redundant">float</warning>)operand);
+ foo((<warning descr="Casting 'operand' to 'double' is redundant">double</warning>)operand);
+ foo((<warning descr="Casting 'operand' to 'boolean' is redundant">boolean</warning>)operand);
+ }
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128101.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128101.java
new file mode 100644
index 000000000000..42be49b62f04
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128101.java
@@ -0,0 +1,29 @@
+class TestIDEA128101 {
+
+ static class Attribute<Y> {};
+ static class Path<X> {};
+
+ static Attribute<Integer> integerAttribute;
+ static Attribute<String> stringAttribute;
+
+ static <Y> Path<Y> createPath(Attribute<Y> attribute) {
+ return new Path<>();
+ }
+ static <Y> Path<Y> createPath1(Attribute<Y> attribute) {
+ return new Path<>();
+ }
+ static <T> void construct(Class<T> aClass, Path<?>... paths) {}
+ static <T, K> void construct1(Class<T> aClass, Path<K>... paths) {}
+ static <T, K> void construct2(Class<T> aClass, Path<? extends K>... paths) {}
+ static <T, K> void construct3(Class<T> aClass, Path<? super K>... paths) {}
+ static <T, K> void construct4(Class<T> aClass, Path<? super K> path1, Path<? super K> path2) {}
+
+ public static void test() {
+ construct(String.class, createPath(integerAttribute), createPath(stringAttribute));
+ construct1<error descr="Cannot resolve method 'construct1(java.lang.Class<java.lang.String>, TestIDEA128101.Path<java.lang.Integer>, TestIDEA128101.Path<java.lang.String>)'">(String.class, createPath(integerAttribute), createPath(stringAttribute))</error>;
+ construct2(String.class, createPath(integerAttribute), createPath(stringAttribute));
+ <error descr="Type parameter K has incompatible upper bounds: Integer and String">construct3(String.class, createPath(integerAttribute), createPath(stringAttribute));</error>
+ <error descr="Type parameter K has incompatible upper bounds: Integer and String">construct4(String.class, createPath(integerAttribute), createPath(stringAttribute));</error>
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128174.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128174.java
new file mode 100644
index 000000000000..650114b06e50
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IDEA128174.java
@@ -0,0 +1,24 @@
+import java.util.Collection;
+import java.util.List;
+
+class Test {
+
+ {
+ Matcher<? super List<String>> m = not(empty());
+ }
+
+ static <E> Matcher<Collection<E>> empty() {
+ return null;
+ }
+
+ static <T> Matcher<T> not(Matcher<T> matcher) {
+ return null;
+ }
+
+ static <T> Matcher<T> not(T value) {
+ return null;
+ }
+
+ static class Matcher<K> {}
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/InferFromConditionalExpressionCondition.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/InferFromConditionalExpressionCondition.java
new file mode 100644
index 000000000000..8fad96c118ed
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/InferFromConditionalExpressionCondition.java
@@ -0,0 +1,14 @@
+class Test {
+ static class TKey<T> {
+ }
+
+ public interface Getter {
+ <T> T getValue(TKey<T> key);
+ }
+
+ static final TKey<Boolean> KEY_B = new TKey<>();
+
+ public static void f(Getter getter) {
+ String name = getter.getValue(KEY_B) ? "foo" : "bar";
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/PrimitiveWrapperConditionInReturnConstraint.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/PrimitiveWrapperConditionInReturnConstraint.java
new file mode 100644
index 000000000000..6788a98b215c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/PrimitiveWrapperConditionInReturnConstraint.java
@@ -0,0 +1,15 @@
+class Test {
+ static class TKey<T> {
+ }
+
+ public interface Getter {
+ <T> T getValue(TKey<T> key);
+ }
+
+ static final TKey<Integer> KEY_I = null;
+
+
+ public static void f(Getter getter, TKey<Integer> key) {
+ double d1 = getter.getValue (key);
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/EffectiveFinal.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/EffectiveFinal.java
index 254ec7191a47..92b268394994 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/EffectiveFinal.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/EffectiveFinal.java
@@ -39,7 +39,7 @@ public class XXX {
void m3(int x, boolean cond) {
int y;
if (cond) y = 1;
- foo(() -> x+<error descr="Variable used in lambda expression should be effectively final">y</error>);
+ foo(() -> x+<error descr="Variable 'y' might not have been initialized">y</error>);
}
void m4(int x, boolean cond) {
@@ -128,3 +128,17 @@ class IDEA114737 {
};
}
}
+
+class IDEA128196 {
+ void a() {
+ int value;
+
+ try {
+ value = 1;
+ } catch (Exception e) {
+ return;
+ }
+
+ new Thread(() -> System.out.println(value));
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/IDEA127765.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/IDEA127765.java
new file mode 100644
index 000000000000..095448e262b3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/IDEA127765.java
@@ -0,0 +1,19 @@
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+class IDEA127765 {
+ void a(final Map<String, Optional<Double>> allValues, final Function<Optional<Double>, Double> get) {
+ final Map<String, Double> presentValues = transformValues(filterValues(allValues, Optional::isPresent), get);
+ }
+
+ public static <K, V1, V2> Map<K, V2> transformValues(Map<K, V1> fromMap, Function<? super V1, V2> function) {
+ return null;
+ }
+
+ public static <K, V> Map<K, V> filterValues(Map<K, V> unfiltered, Predicate<? super V> valuePredicate) {
+ return null;
+ }
+
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterOnVarargsPlace.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterOnVarargsPlace.java
new file mode 100644
index 000000000000..82e3cc9aa3e6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterOnVarargsPlace.java
@@ -0,0 +1,10 @@
+// "Replace with lambda" "true"
+class Test2 {
+
+ void f(Runnable... rs){}
+ {
+ f(null, () -> {
+
+ });
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeOnVarargsPlace.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeOnVarargsPlace.java
new file mode 100644
index 000000000000..af9db7767997
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeOnVarargsPlace.java
@@ -0,0 +1,13 @@
+// "Replace with lambda" "true"
+class Test2 {
+
+ void f(Runnable... rs){}
+ {
+ f(null, new Run<caret>nable() {
+ @Override
+ public void run() {
+
+ }
+ });
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/null/singleExclamationIgnored.java b/java/java-tests/testData/codeInsight/template/postfix/templates/null/singleExclamationIgnored.java
new file mode 100644
index 000000000000..1af8cd0813a9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/template/postfix/templates/null/singleExclamationIgnored.java
@@ -0,0 +1,5 @@
+public class Foo {
+ void m(Object o) {
+ !.null<caret>
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/null/singleExclamationIgnored_after.java b/java/java-tests/testData/codeInsight/template/postfix/templates/null/singleExclamationIgnored_after.java
new file mode 100644
index 000000000000..1334be6b7029
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/template/postfix/templates/null/singleExclamationIgnored_after.java
@@ -0,0 +1,5 @@
+public class Foo {
+ void m(Object o) {
+ !.null <caret>
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/typing/invalidInitialSyntax_after.java b/java/java-tests/testData/codeInsight/typing/invalidInitialSyntax_after.java
new file mode 100644
index 000000000000..08b2afd09cb9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/typing/invalidInitialSyntax_after.java
@@ -0,0 +1,7 @@
+class Foo {
+ public static void main(String[] args) {
+ String s = "";
+ s.replaceAll("\\<caret>");
+ System.out.println();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/typing/invalidInitialSyntax_before.java b/java/java-tests/testData/codeInsight/typing/invalidInitialSyntax_before.java
new file mode 100644
index 000000000000..bee6f10053c2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/typing/invalidInitialSyntax_before.java
@@ -0,0 +1,7 @@
+class Foo {
+ public static void main(String[] args) {
+ String s = "";
+ s.replaceAll("<caret>");
+ System.out.println();
+ }
+}
diff --git a/java/java-tests/testData/find/findInEditor/BasicFind.gold b/java/java-tests/testData/find/findInEditor/BasicFind.gold
index 14e4182499b7..46486765486d 100644
--- a/java/java-tests/testData/find/findInEditor/BasicFind.gold
+++ b/java/java-tests/testData/find/findInEditor/BasicFind.gold
@@ -3,8 +3,7 @@ myStringToFind =a
myStringToReplace =
isReplaceState =false
isWholeWordsOnly =false
-isInStringLiterals =false
-isInComments =false
+searchContext =ANY
isFromCursor =true
isForward =true
isGlobal =true
@@ -22,6 +21,7 @@ isWithSubdirectories =true
fileFilter =null
moduleName =null
customScopeName =null
+searchInProjectFiles =false
--
diff --git a/java/java-tests/testData/find/findInEditor/EmacsLikeFallback.gold b/java/java-tests/testData/find/findInEditor/EmacsLikeFallback.gold
index a2168ba66e2a..bfda616a3ac1 100644
--- a/java/java-tests/testData/find/findInEditor/EmacsLikeFallback.gold
+++ b/java/java-tests/testData/find/findInEditor/EmacsLikeFallback.gold
@@ -3,8 +3,7 @@ myStringToFind =a
myStringToReplace =
isReplaceState =false
isWholeWordsOnly =false
-isInStringLiterals =false
-isInComments =false
+searchContext =ANY
isFromCursor =true
isForward =true
isGlobal =true
@@ -22,6 +21,7 @@ isWithSubdirectories =true
fileFilter =null
moduleName =null
customScopeName =null
+searchInProjectFiles =false
--
@@ -37,8 +37,7 @@ myStringToFind =ab
myStringToReplace =
isReplaceState =false
isWholeWordsOnly =false
-isInStringLiterals =false
-isInComments =false
+searchContext =ANY
isFromCursor =true
isForward =true
isGlobal =true
@@ -56,6 +55,7 @@ isWithSubdirectories =true
fileFilter =null
moduleName =null
customScopeName =null
+searchInProjectFiles =false
--
@@ -70,8 +70,7 @@ myStringToFind =a
myStringToReplace =
isReplaceState =false
isWholeWordsOnly =false
-isInStringLiterals =false
-isInComments =false
+searchContext =ANY
isFromCursor =true
isForward =true
isGlobal =true
@@ -89,6 +88,7 @@ isWithSubdirectories =true
fileFilter =null
moduleName =null
customScopeName =null
+searchInProjectFiles =false
--
diff --git a/java/java-tests/testData/find/findInEditor/ReplacementWithEmptyString.gold b/java/java-tests/testData/find/findInEditor/ReplacementWithEmptyString.gold
index 478eb649684d..a4d44cbfa445 100644
--- a/java/java-tests/testData/find/findInEditor/ReplacementWithEmptyString.gold
+++ b/java/java-tests/testData/find/findInEditor/ReplacementWithEmptyString.gold
@@ -3,8 +3,7 @@ myStringToFind =
myStringToReplace =
isReplaceState =false
isWholeWordsOnly =false
-isInStringLiterals =false
-isInComments =false
+searchContext =ANY
isFromCursor =true
isForward =true
isGlobal =true
@@ -22,6 +21,7 @@ isWithSubdirectories =true
fileFilter =null
moduleName =null
customScopeName =null
+searchInProjectFiles =false
--
@@ -33,8 +33,7 @@ myStringToFind =a
myStringToReplace =
isReplaceState =false
isWholeWordsOnly =false
-isInStringLiterals =false
-isInComments =false
+searchContext =ANY
isFromCursor =true
isForward =true
isGlobal =true
@@ -52,6 +51,7 @@ isWithSubdirectories =true
fileFilter =null
moduleName =null
customScopeName =null
+searchInProjectFiles =false
--
@@ -65,8 +65,7 @@ myStringToFind =a
myStringToReplace =
isReplaceState =true
isWholeWordsOnly =false
-isInStringLiterals =false
-isInComments =false
+searchContext =ANY
isFromCursor =true
isForward =true
isGlobal =true
@@ -84,6 +83,7 @@ isWithSubdirectories =true
fileFilter =null
moduleName =null
customScopeName =null
+searchInProjectFiles =false
--
Replacement Preview: <Empty string>
@@ -99,8 +99,7 @@ myStringToFind =a
myStringToReplace =
isReplaceState =true
isWholeWordsOnly =false
-isInStringLiterals =false
-isInComments =false
+searchContext =ANY
isFromCursor =true
isForward =true
isGlobal =true
@@ -118,6 +117,7 @@ isWithSubdirectories =true
fileFilter =null
moduleName =null
customScopeName =null
+searchInProjectFiles =false
--
diff --git a/java/java-tests/testData/inspection/dataFlow/CheckedExceptionDominance/src/Test.java b/java/java-tests/testData/inspection/dataFlow/CheckedExceptionDominance/src/Test.java
index 4a0a690f0e21..4f0586d30a96 100644
--- a/java/java-tests/testData/inspection/dataFlow/CheckedExceptionDominance/src/Test.java
+++ b/java/java-tests/testData/inspection/dataFlow/CheckedExceptionDominance/src/Test.java
@@ -19,6 +19,6 @@
}
public static void bar() throws CheckedException {
- throw new CheckedException();
+ if (new Random().nextInt() > 2) throw new CheckedException();
}
}
diff --git a/java/java-tests/testData/inspection/dataFlow/IDEADEV10489/expected.xml b/java/java-tests/testData/inspection/dataFlow/IDEADEV10489/expected.xml
index bb6256f74012..4a088210968c 100644
--- a/java/java-tests/testData/inspection/dataFlow/IDEADEV10489/expected.xml
+++ b/java/java-tests/testData/inspection/dataFlow/IDEADEV10489/expected.xml
@@ -7,7 +7,7 @@
</problem>
<problem>
<file>IDEADEV10489.java</file>
- <line>12</line>
+ <line>8</line>
<description>Method invocation 's.length()' may produce NullPointerException</description>
</problem>
</problems> \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/IDEADEV10489/src/IDEADEV10489.java b/java/java-tests/testData/inspection/dataFlow/IDEADEV10489/src/IDEADEV10489.java
index 60259479d353..ee41e588dd3e 100644
--- a/java/java-tests/testData/inspection/dataFlow/IDEADEV10489/src/IDEADEV10489.java
+++ b/java/java-tests/testData/inspection/dataFlow/IDEADEV10489/src/IDEADEV10489.java
@@ -1,7 +1,5 @@
class IDEADEV10489 {
- static String getS() {
- return null;
- }
+ static native String getS();
static void f() {
String s = getS();
@@ -17,7 +15,5 @@ class IDEADEV10489 {
}
}
- private static boolean foo() {
- return false;
- }
+ private static native boolean foo();
} \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/AssertFailInCatch.java b/java/java-tests/testData/inspection/dataFlow/fixture/AssertFailInCatch.java
index 93fcf6d5c2d2..55c7c2b51de0 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/AssertFailInCatch.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/AssertFailInCatch.java
@@ -18,7 +18,5 @@ class Test {
}
}
- private static @NotNull String createString() {
- throw new NullPointerException();
- }
+ private static native @NotNull String createString();
} \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/CatchThrowable.java b/java/java-tests/testData/inspection/dataFlow/fixture/CatchThrowable.java
index ecb9b264bb62..a30d934f64b6 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/CatchThrowable.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/CatchThrowable.java
@@ -1,3 +1,5 @@
+import java.util.Random;
+
class BrokenAlignment {
public static void main(String[] args) {
@@ -20,7 +22,7 @@ class BrokenAlignment {
}
public static void doSomething() {
- throw new RuntimeException("dummy");
+ if (new Random().nextInt() > 2) throw new RuntimeException("dummy");
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ContractWithNoArgs.java b/java/java-tests/testData/inspection/dataFlow/fixture/ContractWithNoArgs.java
new file mode 100644
index 000000000000..006c2e3407ec
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ContractWithNoArgs.java
@@ -0,0 +1,24 @@
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+class Doo {
+
+ @NotNull
+ public String doSomething() {
+ String s = getSomeString();
+ if (s == null) {
+ throwSomeError();
+ }
+ return s;
+ }
+
+ private static void throwSomeError() {
+ throw new RuntimeException();
+ }
+
+ @Nullable
+ public String getSomeString() {
+ return Math.random() > 0.5 ? null : "Yeah";
+ }
+
+}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/CustomTypeQualifierDefault.java b/java/java-tests/testData/inspection/dataFlow/fixture/CustomTypeQualifierDefault.java
new file mode 100644
index 000000000000..e9ec6b1dbe11
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/CustomTypeQualifierDefault.java
@@ -0,0 +1,25 @@
+import foo.*;
+import org.jetbrains.annotations.NotNull;
+
+class Some {
+ void foo(@NotNull String s) {
+ NotNullClass.foo(null);
+ if (<warning descr="Condition 'NotNullClass.foo(s) == null' is always 'false'">NotNullClass.foo(s) == null</warning>) {}
+
+ NullableClass.foo(null);
+ if (NullableClass.foo("a") == null) {}
+
+ AnotherPackageNotNull.foo(null);
+ if (<warning descr="Condition 'AnotherPackageNotNull.foo(s) == null' is always 'false'">AnotherPackageNotNull.foo(s) == null</warning>) {}
+ }
+
+}
+
+@bar.MethodsAreNotNullByDefault
+class NotNullClass {
+ static native Object foo(String s);
+
+}
+class NullableClass {
+ static native Object foo(String s);
+} \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/FloatComparisons.java b/java/java-tests/testData/inspection/dataFlow/fixture/FloatComparisons.java
new file mode 100644
index 000000000000..5c553bcba0bf
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/FloatComparisons.java
@@ -0,0 +1,7 @@
+class Test {
+ public static void testFunc(final float width, final float height) {
+ if (width < 0f || height < 0f) {
+ throw new IllegalArgumentException("Size must be non-negative");
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/renameCollisions/RenameMethodNoCollisionWithOtherSignatureMethodRef.java b/java/java-tests/testData/refactoring/renameCollisions/RenameMethodNoCollisionWithOtherSignatureMethodRef.java
new file mode 100644
index 000000000000..dd815139efa5
--- /dev/null
+++ b/java/java-tests/testData/refactoring/renameCollisions/RenameMethodNoCollisionWithOtherSignatureMethodRef.java
@@ -0,0 +1,9 @@
+class Test {
+
+ static void f<caret>oo() {}
+ static void foo2(int i) {}
+
+ {
+ Runnable r = Test :: foo;
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/renameCollisions/RenameMethodNoCollisionWithOtherSignatureMethodRef.java.after b/java/java-tests/testData/refactoring/renameCollisions/RenameMethodNoCollisionWithOtherSignatureMethodRef.java.after
new file mode 100644
index 000000000000..8dab0803fcec
--- /dev/null
+++ b/java/java-tests/testData/refactoring/renameCollisions/RenameMethodNoCollisionWithOtherSignatureMethodRef.java.after
@@ -0,0 +1,9 @@
+class Test {
+
+ static void foo2() {}
+ static void foo2(int i) {}
+
+ {
+ Runnable r = Test ::foo2;
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/ClsGenerics18HighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/ClsGenerics18HighlightingTest.java
index ae0ec20ab4d2..8383550b3e5c 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/ClsGenerics18HighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/ClsGenerics18HighlightingTest.java
@@ -20,6 +20,8 @@ import com.intellij.pom.java.LanguageLevel;
public class ClsGenerics18HighlightingTest extends ClsGenericsHighlightingTest {
public void testIDEA121866() { doTest(); }
+ public void testIDEA127714() { doTest(); }
+
@Override
protected LanguageLevel getLanguageLevel() {
return LanguageLevel.JDK_1_8;
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java
index 2eecdaa9b221..3f199d44ea13 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java
@@ -17,9 +17,6 @@ package com.intellij.codeInsight;
import com.intellij.JavaTestUtil;
import com.intellij.openapi.actionSystem.IdeActions;
-import com.intellij.openapi.roots.LanguageLevelProjectExtension;
-import com.intellij.pom.java.LanguageLevel;
-import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
@@ -54,6 +51,18 @@ public class CompleteStatementTest extends EditorActionTestCase {
public void testCompleteCatchLParen() throws Exception { doTest(); }
+ public void testAlreadyCompleteCatch() throws Exception {
+ CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
+ int old = settings.BRACE_STYLE;
+ settings.BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE;
+ try {
+ doTest();
+ }
+ finally {
+ settings.BRACE_STYLE = old;
+ }
+ }
+
public void testCompleteCatchWithExpression() throws Exception { doTest(); }
public void testCompleteCatchBody() throws Exception { doTest(); }
@@ -171,8 +180,6 @@ public class CompleteStatementTest extends EditorActionTestCase {
}
public void testSCR36110() throws Exception {
- JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
- LanguageLevel old = LanguageLevelProjectExtension.getInstance(facade.getProject()).getLanguageLevel();
doTest();
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java
index f59162a6d5b2..9ca3b6084a43 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java
@@ -16,6 +16,7 @@
package com.intellij.codeInsight;
import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.psi.PsiDocumentManager;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
@@ -65,6 +66,14 @@ public class JavaTypingTest extends LightPlatformCodeInsightFixtureTestCase {
myFixture.checkResultByFile(getTestName(true) + "_after.java");
}
+ public void testInvalidInitialSyntax() {
+ myFixture.configureByFile(getTestName(true) + "_before.java");
+ myFixture.type('\\');
+ PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); // emulates background commit after typing first character
+ myFixture.type('\\');
+ myFixture.checkResultByFile(getTestName(true) + "_after.java");
+ }
+
private void doTest(char c) {
myFixture.configureByFile(getTestName(true) + "_before.java");
myFixture.type(c);
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 77b4c0cc64a7..f5fc39041106 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
@@ -1423,6 +1423,11 @@ class XInternalError {}
checkResult()
}
+ public void testMulticaretCompletionFromNonPrimaryCaret() {
+ configure()
+ myFixture.assertPreferredCompletionItems(0, "arraycopy")
+ }
+
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/completion/SmartTypeCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy
index 1d258fe01367..f37b90e21523 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy
@@ -160,6 +160,10 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase {
checkPreferredItems(0, "myVersion", "getVersion", "getSelectedVersion", "calculateVersion");
}
+ public void testPreferFieldsToConstants() {
+ checkPreferredItems(0, "dateField", "LocalDate.MAX", "LocalDate.MIN");
+ }
+
public void testPreferParametersToGetters() throws Throwable {
checkPreferredItems(0, "a", "I._1", "getLastI", "valueOf");
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java
index d2e8825cc16d..5153f19fe94a 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java
@@ -716,7 +716,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
public void testMethodColon() throws Exception { doFirstItemTest(':'); }
public void testVariableColon() throws Exception { doFirstItemTest(':'); }
- private void doFirstItemTest(char c) throws Exception {
+ private void doFirstItemTest(char c) {
configureByTestName();
select(c);
checkResultByTestName();
@@ -824,6 +824,8 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
doActionTest();
}
+ public void testDontSuggestWildcardGenerics() { doItemTest(); }
+
public void testCastWith2TypeParameters() throws Throwable { doTest(); }
public void testClassLiteralInArrayAnnoInitializer() throws Throwable { doTest(); }
public void testClassLiteralInArrayAnnoInitializer2() throws Throwable { doTest(); }
@@ -1141,7 +1143,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
checkResultByTestName();
}
- private void doItemTest() throws Exception {
+ private void doItemTest() {
doFirstItemTest('\n');
}
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 79506280a778..6ccefa35ae51 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
@@ -188,6 +188,22 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
doTest();
}
+ public void testInferFromConditionalExpressionCondition() throws Exception {
+ doTest();
+ }
+
+ public void testPrimitiveWrapperConditionInReturnConstraint() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA128174() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA128101() throws Exception {
+ doTest();
+ }
+
private void doTest() throws Exception {
doTest(false);
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
index fbf8036e8e35..156aac5613c1 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
@@ -106,6 +106,10 @@ public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
+ public void testIDEA127765() throws Exception {
+ doTest();
+ }
+
private void doTest() {
doTest(false);
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingGotoTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingGotoTest.java
new file mode 100644
index 000000000000..b94e54d91323
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingGotoTest.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.codeInsight.folding;
+
+import com.intellij.codeInsight.navigation.actions.GotoDeclarationAction;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.ex.FoldingModelEx;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
+
+public class JavaFoldingGotoTest extends JavaCodeInsightFixtureTestCase {
+
+ public void testIDEA127145() {
+ PsiFile file = myFixture.addFileToProject("Program.java",
+ "import java.io.InputStream;\n" +
+ "import java.util.HashMap;\n" +
+ "import java.util.Map;\n" +
+ "\n" +
+ "class Program {\n" +
+ " private static InputStream getFile(String name, Map<String, Object> args) {\n" +
+ " return Program.class.getResourceAsStream(name);\n" +
+ " }\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " // Ctrl + B or Ctrl + Left Mouse Button work correctly for following string:\n" +
+ " final String name = \"file.sql\";\n" +
+ " // But it jumps only to folder in following case:\n" +
+ " final InputStream inputStream = getFile(\"dir/fil<caret>e.sql\", new HashMap<String, Object>());\n" +
+ " }\n" +
+ "}");
+
+ PsiFile fileSql = myFixture.addFileToProject("dir/file.sql", "select 1;");
+ myFixture.configureFromExistingVirtualFile(file.getVirtualFile());
+
+ Editor editor = myFixture.getEditor();
+ CodeFoldingManager.getInstance(getProject()).buildInitialFoldings(editor);
+ FoldingModelEx foldingModel = (FoldingModelEx)editor.getFoldingModel();
+ foldingModel.rebuild();
+ myFixture.doHighlighting();
+
+ PsiElement element = GotoDeclarationAction.findTargetElement(getProject(), editor, editor.getCaretModel().getOffset());
+ assertTrue("Should navigate to: file.sql instead of " + element, element != null && element.equals(fileSql));
+ }
+
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy
index 5d823e001f82..095de51543af 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy
@@ -568,14 +568,20 @@ class Test {
public void "test fold one-line methods"() {
configure """class Foo {
+ @Override
int someMethod() {
return 0;
}
+ int someOtherMethod(
+ int param) {
+ return 0;
+ }
+
}"""
PsiClass fooClass = JavaPsiFacade.getInstance(project).findClass('Foo', GlobalSearchScope.allScope(project))
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
- assert regions.size() == 2
+ assert regions.size() == 3
checkAccessorFolding(regions[0], regions[1], fooClass.methods[0])
}
@@ -792,13 +798,14 @@ public class CharSymbol {
assert regions[3].placeholderText == 'seq: "Hi!"'
}
- public void "test inline negative numbers (IDEA-126753)"() {
+ public void "test inline negative and positive numbers"() {
def text = """
public class CharSymbol {
public void main() {
Object obj = new Object();
count(-1, obj);
+ count(+1, obj);
}
public void count(int test, Object obj) {
@@ -809,10 +816,13 @@ public class CharSymbol {
"""
configure text
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
- assert regions.size() == 3
+ assert regions.size() == 4
checkRangeOffsetByPositionInText(regions[1], text, "-1")
assert regions[1].placeholderText == "test: -1"
+
+ checkRangeOffsetByPositionInText(regions[2], text, "+1")
+ assert regions[2].placeholderText == "test: +1"
}
public void "test inline constructor literal arguments names"() {
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/NullPostfixTemplateTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/NullPostfixTemplateTest.java
index 7f47795881bc..70061e56afa9 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/NullPostfixTemplateTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/NullPostfixTemplateTest.java
@@ -38,4 +38,9 @@ public class NullPostfixTemplateTest extends PostfixTemplateTestCase {
public void testSecondStatement() {
doTest();
}
+
+
+ public void testSingleExclamationIgnored() {
+ doTest();
+ }
} \ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy b/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy
index 23eac589e2db..89762efe5dd2 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy
@@ -228,6 +228,34 @@ class ContractInferenceFromSourceTest extends LightCodeInsightFixtureTestCase {
assert c == []
}
+ public void "test boolean autoboxing in delegation"() {
+ def c = inferContracts("""
+ static Boolean test04(String s) {
+ return test03(s);
+ }
+ static boolean test03(String s) {
+ return s == null;
+ }
+ """)
+ assert c == []
+ }
+
+ public void "test boolean auto-unboxing"() {
+ def c = inferContracts("""
+ static boolean test02(String s) {
+ return test01(s);
+ }
+
+ static Boolean test01(String s) {
+ if (s == null)
+ return new Boolean(false);
+ else
+ return null;
+ }
+ """)
+ assert c == []
+ }
+
public void "test non-returning delegation"() {
def c = inferContracts("""
static void test2(Object o) {
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
index 4cba2ab918a7..33eb32eb0ec6 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
@@ -18,6 +18,7 @@ package com.intellij.codeInspection;
import com.intellij.JavaTestUtil;
import com.intellij.codeInspection.dataFlow.DataFlowInspection;
import com.intellij.testFramework.LightProjectDescriptor;
+import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
@@ -251,15 +252,17 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
public void testRootThrowableCause() { doTest(); }
public void testUseInferredContracts() { doTest(); }
+ public void testContractWithNoArgs() { doTest(); }
public void testContractInferenceBewareOverriding() { doTest(); }
public void testNumberComparisonsWhenValueIsKnown() { doTest(); }
+ public void testFloatComparisons() { doTest(); }
public void testAccessingSameArrayElements() { doTest(); }
public void testParametersAreNonnullByDefault() {
- myFixture.addClass("package javax.annotation; public @interface ParametersAreNonnullByDefault {}");
- myFixture.addClass("package javax.annotation; public @interface ParametersAreNullableByDefault {}");
+ addJavaxNullabilityAnnotations(myFixture);
+ addJavaxDefaultNullabilityAnnotations(myFixture);
myFixture.addClass("package foo; public class AnotherPackageNotNull { public static void foo(String s) {}}");
myFixture.addFileToProject("foo/package-info.java", "@javax.annotation.ParametersAreNonnullByDefault package foo;");
@@ -267,6 +270,37 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
doTest();
}
+ public static void addJavaxDefaultNullabilityAnnotations(final JavaCodeInsightTestFixture fixture) {
+ fixture.addClass("package javax.annotation;" +
+ "@javax.annotation.meta.TypeQualifierDefault(java.lang.annotation.ElementType.PARAMETER) @javax.annotation.Nonnull " +
+ "public @interface ParametersAreNonnullByDefault {}");
+ fixture.addClass("package javax.annotation;" +
+ "@javax.annotation.meta.TypeQualifierDefault(java.lang.annotation.ElementType.PARAMETER) @javax.annotation.Nullable " +
+ "public @interface ParametersAreNullableByDefault {}");
+ }
+
+ public static void addJavaxNullabilityAnnotations(final JavaCodeInsightTestFixture fixture) {
+ fixture.addClass("package javax.annotation;" +
+ "public @interface Nonnull {}");
+ fixture.addClass("package javax.annotation;" +
+ "public @interface Nullable {}");
+ fixture.addClass("package javax.annotation.meta;" +
+ "public @interface TypeQualifierDefault { java.lang.annotation.ElementType[] value() default {};}");
+ }
+
+ public void testCustomTypeQualifierDefault() {
+ addJavaxNullabilityAnnotations(myFixture);
+ myFixture.addClass("package bar;" +
+ "@javax.annotation.meta.TypeQualifierDefault(java.lang.annotation.ElementType.METHOD) @javax.annotation.Nonnull " +
+ "public @interface MethodsAreNotNullByDefault {}");
+
+ myFixture.addClass("package foo; public class AnotherPackageNotNull { public static native Object foo(String s); }");
+ myFixture.addFileToProject("foo/package-info.java", "@bar.MethodsAreNotNullByDefault package foo;");
+
+ myFixture.enableInspections(new DataFlowInspection());
+ myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
+ }
+
public void testTrueOrEqualsSomething() {
doTest();
myFixture.launchAction(myFixture.findSingleIntention("Remove redundant assignment"));
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java
index e925dd49a8ea..3520ec08d750 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java
@@ -40,8 +40,8 @@ public class NullableStuffInspectionTest extends LightCodeInsightFixtureTestCase
}
public void testHonorSuperParameterDefault() {
- myFixture.addClass("package javax.annotation; public @interface ParametersAreNonnullByDefault {}");
- myFixture.addClass("package javax.annotation; public @interface Nullable {}");
+ DataFlowInspectionTest.addJavaxNullabilityAnnotations(myFixture);
+ DataFlowInspectionTest.addJavaxDefaultNullabilityAnnotations(myFixture);
myFixture.addFileToProject("foo/package-info.java", "@javax.annotation.ParametersAreNonnullByDefault package foo;");
myFixture.addClass("import javax.annotation.*; package foo; public interface NullableFunction { void fun(@Nullable Object o); }");
@@ -51,7 +51,8 @@ public class NullableStuffInspectionTest extends LightCodeInsightFixtureTestCase
}
public void testHonorThisParameterDefault() {
- myFixture.addClass("package javax.annotation; public @interface ParametersAreNonnullByDefault {}");
+ DataFlowInspectionTest.addJavaxNullabilityAnnotations(myFixture);
+ DataFlowInspectionTest.addJavaxDefaultNullabilityAnnotations(myFixture);
myFixture.addFileToProject("foo/package-info.java", "@javax.annotation.ParametersAreNonnullByDefault package foo;");
myFixture.configureFromExistingVirtualFile(myFixture.copyFileToProject(getTestName(false) + ".java", "foo/Classes.java"));
@@ -60,8 +61,8 @@ public class NullableStuffInspectionTest extends LightCodeInsightFixtureTestCase
}
public void testHonorParameterDefaultInSetters() {
- myFixture.addClass("package javax.annotation; public @interface ParametersAreNonnullByDefault {}");
- myFixture.addClass("package javax.annotation; public @interface Nullable {}");
+ DataFlowInspectionTest.addJavaxNullabilityAnnotations(myFixture);
+ DataFlowInspectionTest.addJavaxDefaultNullabilityAnnotations(myFixture);
myFixture.addFileToProject("foo/package-info.java", "@javax.annotation.ParametersAreNonnullByDefault package foo;");
myFixture.configureFromExistingVirtualFile(myFixture.copyFileToProject(getTestName(false) + ".java", "foo/Classes.java"));
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisTest.java
index 09fa87fa95e9..9d26fd804f68 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisTest.java
@@ -183,7 +183,7 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
private void checkCompoundId(Method method, PsiMethod psiMethod, boolean noKey) throws IOException {
Direction direction = new Out();
- int psiKey = myBytecodeAnalysisConverter.mkPsiKey(psiMethod, direction);
+ long psiKey = myBytecodeAnalysisConverter.mkPsiKey(psiMethod, direction);
if (noKey) {
assertTrue(-1 == psiKey);
return;
@@ -192,7 +192,7 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
assertFalse(-1 == psiKey);
}
- int asmKey = myBytecodeAnalysisConverter.mkAsmKey(new Key(method, direction, true));
+ long asmKey = myBytecodeAnalysisConverter.mkAsmKey(new Key(method, direction, true));
Assert.assertEquals(asmKey, psiKey);
}
diff --git a/java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java b/java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java
index 02f8c589c43b..3cc6c19618a1 100644
--- a/java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java
+++ b/java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java
@@ -19,7 +19,9 @@ import com.intellij.find.editorHeaderActions.*;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.IdeActions;
+import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.util.Getter;
+import com.intellij.testFramework.fixtures.EditorMouseFixture;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import javax.swing.text.JTextComponent;
@@ -58,7 +60,7 @@ public class FindInEditorMultiCaretTest extends LightPlatformCodeInsightFixtureT
assertNull(getEditorSearchComponent());
}
- public void testActionsWorkFromEditor() throws IOException {
+ public void testActionsInEditorWorkIndependently() throws IOException {
init("abc\n" +
"abc\n" +
"abc");
@@ -67,27 +69,29 @@ public class FindInEditorMultiCaretTest extends LightPlatformCodeInsightFixtureT
checkResultByText("a<selection>b<caret></selection>c\n" +
"abc\n" +
"abc");
+ new EditorMouseFixture((EditorImpl)myFixture.getEditor()).clickAt(0, 1);
addOccurrenceFromEditor();
- checkResultByText("a<selection>b<caret></selection>c\n" +
- "a<selection>b<caret></selection>c\n" +
+ addOccurrenceFromEditor();
+ checkResultByText("<selection>a<caret>bc</selection>\n" +
+ "<selection>a<caret>bc</selection>\n" +
"abc");
nextOccurrenceFromEditor();
- checkResultByText("a<selection>b<caret></selection>c\n" +
+ checkResultByText("<selection>a<caret>bc</selection>\n" +
"abc\n" +
- "a<selection>b<caret></selection>c");
+ "<selection>a<caret>bc</selection>");
prevOccurrenceFromEditor();
- checkResultByText("a<selection>b<caret></selection>c\n" +
- "a<selection>b<caret></selection>c\n" +
+ checkResultByText("<selection>a<caret>bc</selection>\n" +
+ "<selection>a<caret>bc</selection>\n" +
"abc");
removeOccurrenceFromEditor();
- checkResultByText("a<selection>b<caret></selection>c\n" +
+ checkResultByText("<selection>a<caret>bc</selection>\n" +
"abc\n" +
"abc");
allOccurrencesFromEditor();
- checkResultByText("a<selection>b<caret></selection>c\n" +
- "a<selection>b<caret></selection>c\n" +
- "a<selection>b<caret></selection>c");
- assertNull(getEditorSearchComponent());
+ checkResultByText("<selection>a<caret>bc</selection>\n" +
+ "<selection>a<caret>bc</selection>\n" +
+ "<selection>a<caret>bc</selection>");
+ assertNotNull(getEditorSearchComponent());
}
public void testCloseRetainsMulticaretSelection() throws IOException {
diff --git a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
index 92caad03d8ef..f83d836bb55a 100644
--- a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
+++ b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
@@ -579,7 +579,7 @@ public class FindManagerTest extends DaemonAnalyzerTestCase {
FindModel findModel = FindManagerTestUtils.configureFindModel("done");
String text = "/** done done done */";
- findModel.setInCommentsOnly(true);
+ findModel.setSearchContext(FindModel.SearchContext.IN_COMMENTS);
FindManagerTestUtils.runFindForwardAndBackward(myFindManager, findModel, text);
findModel.setRegularExpressions(true);
@@ -592,7 +592,7 @@ public class FindManagerTest extends DaemonAnalyzerTestCase {
String prefix = "/*";
String text = prefix + "done*/";
- findModel.setInCommentsOnly(true);
+ findModel.setSearchContext(FindModel.SearchContext.IN_COMMENTS);
LightVirtualFile file = new LightVirtualFile("A.java", text);
FindResult findResult = myFindManager.findString(text, prefix.length(), findModel, file);
@@ -615,8 +615,7 @@ public class FindManagerTest extends DaemonAnalyzerTestCase {
FindModel findModel = FindManagerTestUtils.configureFindModel("^done$");
findModel.setRegularExpressions(true);
- findModel.setInStringLiteralsOnly(true);
- findModel.setInCommentsOnly(false);
+ findModel.setSearchContext(FindModel.SearchContext.IN_STRING_LITERALS);
String text = "\"done\"; 'done'; 'done' \"done2\"";
FindManagerTestUtils.runFindForwardAndBackward(myFindManager, findModel, text, "java");
@@ -633,7 +632,7 @@ public class FindManagerTest extends DaemonAnalyzerTestCase {
String text = "/** do ne do ne do ne */";
- findModel.setInCommentsOnly(true);
+ findModel.setSearchContext(FindModel.SearchContext.IN_COMMENTS);
FindManagerTestUtils.runFindForwardAndBackward(myFindManager, findModel, text, "java");
}
@@ -651,4 +650,42 @@ public class FindManagerTest extends DaemonAnalyzerTestCase {
findModel.setWholeWordsOnly(true);
assertSize(1, findUsages(findModel));
}
+
+ public void testFindExceptComments() {
+ FindModel findModel = FindManagerTestUtils.configureFindModel("done");
+
+ String prefix = "/*";
+ String text = prefix + "done*/done";
+
+ findModel.setSearchContext(FindModel.SearchContext.EXCEPT_COMMENTS);
+ LightVirtualFile file = new LightVirtualFile("A.java", text);
+
+ FindResult findResult = myFindManager.findString(text, prefix.length(), findModel, file);
+ assertTrue(findResult.isStringFound());
+ assertTrue(findResult.getStartOffset() > prefix.length());
+
+ findModel.setRegularExpressions(true);
+ findResult = myFindManager.findString(text, prefix.length(), findModel, file);
+ assertTrue(findResult.isStringFound());
+ assertTrue(findResult.getStartOffset() > prefix.length());
+ }
+
+ public void testFindExceptLiterals() {
+ FindModel findModel = FindManagerTestUtils.configureFindModel("done");
+
+ String prefix = "\"";
+ String text = prefix + "done\"done";
+
+ findModel.setSearchContext(FindModel.SearchContext.EXCEPT_STRING_LITERALS);
+ LightVirtualFile file = new LightVirtualFile("A.java", text);
+
+ FindResult findResult = myFindManager.findString(text, prefix.length(), findModel, file);
+ assertTrue(findResult.isStringFound());
+ assertTrue(findResult.getStartOffset() > prefix.length());
+
+ findModel.setRegularExpressions(true);
+ findResult = myFindManager.findString(text, prefix.length(), findModel, file);
+ assertTrue(findResult.isStringFound());
+ assertTrue(findResult.getStartOffset() > prefix.length());
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy
index dabe06ba79fa..9a97a825964a 100644
--- a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy
@@ -24,7 +24,6 @@ import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.util.Consumer
import com.intellij.util.concurrency.Semaphore
import org.jetbrains.annotations.NotNull
-
/**
* @author peter
*/
@@ -197,6 +196,33 @@ class Intf {
assert getPopupElements(new GotoClassModel2(project), 'Bar:[2,3]') == [c]
}
+ public void "test dollar"() {
+ def bar = myFixture.addClass("package foo; class Bar { class Foo {} }")
+ def foo = bar.innerClasses[0]
+ myFixture.addClass("package goo; class Goo { }")
+ assert getPopupElements(new GotoClassModel2(project), 'Bar$Foo') == [foo]
+ assert getPopupElements(new GotoClassModel2(project), 'foo.Bar$Foo') == [foo]
+ assert getPopupElements(new GotoClassModel2(project), 'foo.B$F') == [foo]
+ assert !getPopupElements(new GotoClassModel2(project), 'foo$Foo')
+ assert !getPopupElements(new GotoClassModel2(project), 'foo$Bar')
+ assert !getPopupElements(new GotoClassModel2(project), 'foo$Bar$Foo')
+ assert !getPopupElements(new GotoClassModel2(project), 'foo$Goo')
+ }
+
+ public void "test anonymous classes"() {
+ def goo = myFixture.addClass("package goo; class Goo { Runnable r = new Runnable() {}; }")
+ assert getPopupElements(new GotoClassModel2(project), 'Goo$1') == [goo]
+ }
+
+ public void "test qualified name matching"() {
+ def bar = myFixture.addClass("package foo.bar; class Bar { }")
+ def bar2 = myFixture.addClass("package goo.baz; class Bar { }")
+ assert getPopupElements(new GotoClassModel2(project), 'foo.Bar') == [bar]
+ assert getPopupElements(new GotoClassModel2(project), 'foo.bar.Bar') == [bar]
+ assert getPopupElements(new GotoClassModel2(project), 'goo.Bar') == [bar2]
+ assert getPopupElements(new GotoClassModel2(project), 'goo.baz.Bar') == [bar2]
+ }
+
public void "test super method in jdk"() {
def ourRun = myFixture.addClass("package foo.bar; class Goo implements Runnable { public void run() {} }").methods[0]
def sdkRun
diff --git a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java
index 1e3e08a33ae7..56624594bb0e 100644
--- a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java
+++ b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java
@@ -49,7 +49,7 @@ import static java.util.Collections.singletonList;
public class DirectoryIndexTest extends IdeaTestCase {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.DirectoryIndexTest");
- private DirectoryIndex myIndex;
+ private DirectoryIndexImpl myIndex;
private Module myModule2, myModule3;
private VirtualFile myRootVFile;
@@ -65,6 +65,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
private VirtualFile myModule1OutputDir;
private VirtualFile myResDir, myTestResDir;
private VirtualFile myExcludedLibSrcDir, myExcludedLibClsDir;
+ private ProjectFileIndex myFileIndex;
@Override
protected void setUp() throws Exception {
@@ -176,7 +177,8 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
});
- myIndex = DirectoryIndex.getInstance(myProject);
+ myIndex = (DirectoryIndexImpl)DirectoryIndex.getInstance(myProject);
+ myFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
// to not interfere with previous test firing vfs events
VirtualFileManager.getInstance().syncRefresh();
}
@@ -221,12 +223,12 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile cvs = myPack1Dir.createChildDirectory(this, "CVS");
assertNotInProject(cvs);
- assertNull(ProjectRootManager.getInstance(myProject).getFileIndex().getPackageNameByDirectory(cvs));
+ assertNull(myFileIndex.getPackageNameByDirectory(cvs));
}
public void testDirsByPackageName() throws IOException {
- checkPackage("", true, mySrcDir1, myTestSrc1, myResDir, myTestResDir, myFileLibSrc, myFileLibCls, mySrcDir2, myLibSrcDir, myLibClsDir);
- checkPackage("", false, mySrcDir1, myTestSrc1, myResDir, myTestResDir, myFileLibCls, mySrcDir2, myLibClsDir);
+ checkPackage("", true, mySrcDir1, myTestSrc1, myResDir, myTestResDir, mySrcDir2, myLibSrcDir, myLibClsDir);
+ checkPackage("", false, mySrcDir1, myTestSrc1, myResDir, myTestResDir, mySrcDir2, myLibClsDir);
checkPackage("pack1", true, myPack1Dir);
checkPackage("pack1", false, myPack1Dir);
@@ -257,6 +259,18 @@ public class DirectoryIndexTest extends IdeaTestCase {
checkPackage("pack1", true, myPack1Dir, myModule3Dir);
}
+ public void testPackageDirectoriesWithDots() throws IOException {
+ VirtualFile fooBar = mySrcDir1.createChildDirectory(this, "foo.bar");
+ VirtualFile goo1 = fooBar.createChildDirectory(this, "goo");
+ VirtualFile foo = mySrcDir2.createChildDirectory(this, "foo");
+ VirtualFile bar = foo.createChildDirectory(this, "bar");
+ VirtualFile goo2 = bar.createChildDirectory(this, "goo");
+
+ checkPackage("foo", false, foo);
+ checkPackage("foo.bar", false, bar, fooBar);
+ checkPackage("foo.bar.goo", false, goo2, goo1);
+ }
+
public void testCreateDir() throws Exception {
String path = mySrcDir1.getPath().replace('/', File.separatorChar);
assertTrue(new File(path + File.separatorChar + "dir1" + File.separatorChar + "dir2").mkdirs());
@@ -362,7 +376,8 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile ignoredFile = myModule1Dir.createChildData(this, "CVS");
DirectoryInfo info = myIndex.getInfoForFile(ignoredFile);
assertTrue(info.isIgnored());
- assertTrue(ProjectRootManager.getInstance(myProject).getFileIndex().isExcluded(ignoredFile));
+ assertTrue(myFileIndex.isExcluded(ignoredFile));
+ assertTrue(myFileIndex.isUnderIgnored(ignoredFile));
}
public void testAddModule() throws Exception {
@@ -386,10 +401,12 @@ public class DirectoryIndexTest extends IdeaTestCase {
public void testModuleUnderIgnoredDir() throws IOException {
final VirtualFile ignored = myRootVFile.createChildDirectory(this, "RCS");
assertTrue(FileTypeManager.getInstance().isFileIgnored(ignored));
- assertTrue(ProjectRootManager.getInstance(myProject).getFileIndex().isExcluded(ignored));
+ assertTrue(myFileIndex.isExcluded(ignored));
+ assertTrue(myFileIndex.isUnderIgnored(ignored));
final VirtualFile module4 = ignored.createChildDirectory(this, "module4");
assertFalse(FileTypeManager.getInstance().isFileIgnored(module4));
- assertTrue(ProjectRootManager.getInstance(myProject).getFileIndex().isExcluded(module4));
+ assertTrue(myFileIndex.isExcluded(module4));
+ assertTrue(myFileIndex.isUnderIgnored(module4));
new WriteCommandAction.Simple(getProject()) {
@Override
@@ -425,11 +442,12 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
public void testExcludedDirsInLibraries() {
- ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex();
- assertFalse(index.isInLibraryClasses(myExcludedLibClsDir));
- assertTrue(index.isExcluded(myExcludedLibClsDir));
- assertFalse(index.isInLibrarySource(myExcludedLibSrcDir));
- assertTrue(index.isExcluded(myExcludedLibSrcDir));
+ assertFalse(myFileIndex.isInLibraryClasses(myExcludedLibClsDir));
+ assertTrue(myFileIndex.isExcluded(myExcludedLibClsDir));
+ assertFalse(myFileIndex.isUnderIgnored(myExcludedLibClsDir));
+ assertFalse(myFileIndex.isInLibrarySource(myExcludedLibSrcDir));
+ assertTrue(myFileIndex.isExcluded(myExcludedLibSrcDir));
+ assertFalse(myFileIndex.isUnderIgnored(myExcludedLibSrcDir));
}
public void testExplicitExcludeOfInner() throws Exception {
@@ -469,12 +487,12 @@ public class DirectoryIndexTest extends IdeaTestCase {
ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Collections.<String>emptyList(), Arrays.asList(mySrcDir1.getUrl()));
checkInfo(mySrcDir1, myModule, false, true, "", JavaSourceRootType.SOURCE, myModule, myModule);
- OrderEntry[] entries = myIndex.getInfoForFile(mySrcDir1).getOrderEntries();
+ OrderEntry[] entries = myIndex.getOrderEntries(myIndex.getInfoForFile(mySrcDir1));
assertInstanceOf(entries[0], LibraryOrderEntry.class);
assertInstanceOf(entries[1], ModuleSourceOrderEntry.class);
checkInfo(myTestSrc1, myModule, false, true, "testSrc", JavaSourceRootType.TEST_SOURCE, myModule, myModule);
- entries = myIndex.getInfoForFile(myTestSrc1).getOrderEntries();
+ entries = myIndex.getOrderEntries(myIndex.getInfoForFile(myTestSrc1));
assertInstanceOf(entries[0], LibraryOrderEntry.class);
assertInstanceOf(entries[1], ModuleSourceOrderEntry.class);
}
@@ -482,7 +500,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
public void testModuleSourceAsLibraryClasses() throws Exception {
ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Arrays.asList(mySrcDir1.getUrl()), Collections.<String>emptyList());
checkInfo(mySrcDir1, myModule, true, false, "", JavaSourceRootType.SOURCE, myModule);
- assertInstanceOf(assertOneElement(assertInProject(mySrcDir1).getOrderEntries()), ModuleSourceOrderEntry.class);
+ assertInstanceOf(assertOneElement(myIndex.getOrderEntries(assertInProject(mySrcDir1))), ModuleSourceOrderEntry.class);
}
public void testModulesWithSameSourceContentRoot() {
@@ -645,7 +663,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
checkInfo(myLibSrcDir, myModule, true, true, "", null, myModule, myModule3);
checkInfo(myResDir, myModule, true, false, "", JavaResourceRootType.RESOURCE, myModule);
- assertInstanceOf(assertOneElement(assertInProject(myResDir).getOrderEntries()), ModuleSourceOrderEntry.class);
+ assertInstanceOf(assertOneElement(myIndex.getOrderEntries(assertInProject(myResDir))), ModuleSourceOrderEntry.class);
checkInfo(myExcludedLibSrcDir, null, true, false, "lib.src.exc", null, myModule3, myModule);
checkInfo(myExcludedLibClsDir, null, true, false, "lib.cls.exc", null, myModule3);
@@ -661,10 +679,10 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
public void testExcludeCompilerOutputOutsideOfContentRoot() throws Exception {
- final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
- assertTrue(fileIndex.isExcluded(myOutputDir));
- assertTrue(fileIndex.isExcluded(myModule1OutputDir));
- assertFalse(fileIndex.isExcluded(myOutputDir.getParent()));
+ assertTrue(myFileIndex.isExcluded(myOutputDir));
+ assertFalse(myFileIndex.isUnderIgnored(myOutputDir));
+ assertTrue(myFileIndex.isExcluded(myModule1OutputDir));
+ assertFalse(myFileIndex.isExcluded(myOutputDir.getParent()));
assertExcludedFromProject(myOutputDir);
assertExcludedFromProject(myModule1OutputDir);
String moduleOutputUrl = myModule1OutputDir.getUrl();
@@ -677,7 +695,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertExcludedFromProject(myOutputDir);
assertExcludedFromProject(myModule1OutputDir);
- assertTrue(fileIndex.isExcluded(myModule1OutputDir));
+ assertTrue(myFileIndex.isExcluded(myModule1OutputDir));
PsiTestUtil.setCompilerOutputPath(myModule, moduleOutputUrl, true);
PsiTestUtil.setCompilerOutputPath(myModule2, moduleOutputUrl, false);
@@ -703,49 +721,47 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
public void testFileContentAndSourceRoots() throws IOException {
- ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
-
VirtualFile fileRoot = myRootVFile.createChildData(this, "fileRoot.txt");
VirtualFile fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt");
VirtualFile fileTestSourceRoot = myRootVFile.createChildData(this, "fileTestSourceRoot.txt");
assertNotInProject(fileRoot);
- assertFalse(fileIndex.isInContent(fileRoot));
- assertIteratedContent(fileIndex, null, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot));
+ assertFalse(myFileIndex.isInContent(fileRoot));
+ assertIteratedContent(myFileIndex, null, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot));
ContentEntry contentEntry = PsiTestUtil.addContentRoot(myModule, fileRoot);
assertEquals(fileRoot, contentEntry.getFile());
checkInfo(fileRoot, myModule, false, false, "", null);
- assertTrue(fileIndex.isInContent(fileRoot));
- assertFalse(fileIndex.isInSource(fileRoot));
+ assertTrue(myFileIndex.isInContent(fileRoot));
+ assertFalse(myFileIndex.isInSource(fileRoot));
PsiTestUtil.addContentRoot(myModule, fileSourceRoot);
PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
- assertTrue(fileIndex.isInContent(fileSourceRoot));
- assertTrue(fileIndex.isInSource(fileSourceRoot));
+ assertTrue(myFileIndex.isInContent(fileSourceRoot));
+ assertTrue(myFileIndex.isInSource(fileSourceRoot));
PsiTestUtil.addContentRoot(myModule, fileTestSourceRoot);
PsiTestUtil.addSourceRoot(myModule, fileTestSourceRoot, true);
checkInfo(fileTestSourceRoot, myModule, false, false, "", JavaSourceRootType.TEST_SOURCE, myModule);
- assertTrue(fileIndex.isInContent(fileTestSourceRoot));
- assertTrue(fileIndex.isInSource(fileTestSourceRoot));
+ assertTrue(myFileIndex.isInContent(fileTestSourceRoot));
+ assertTrue(myFileIndex.isInSource(fileTestSourceRoot));
- assertIteratedContent(fileIndex, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot), null);
+ assertIteratedContent(myFileIndex, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot), null);
// removing file source root
PsiTestUtil.removeSourceRoot(myModule, fileTestSourceRoot);
checkInfo(fileTestSourceRoot, myModule, false, false, "", null);
- assertTrue(fileIndex.isInContent(fileTestSourceRoot));
- assertFalse(fileIndex.isInSource(fileTestSourceRoot));
- assertIteratedContent(fileIndex, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot), null);
+ assertTrue(myFileIndex.isInContent(fileTestSourceRoot));
+ assertFalse(myFileIndex.isInSource(fileTestSourceRoot));
+ assertIteratedContent(myFileIndex, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot), null);
// removing file content root
- PsiTestUtil.removeContentEntry(myModule, contentEntry);
+ PsiTestUtil.removeContentEntry(myModule, contentEntry.getFile());
assertNotInProject(fileRoot);
- assertFalse(fileIndex.isInContent(fileRoot));
- assertFalse(fileIndex.isInSource(fileRoot));
- assertIteratedContent(fileIndex, Arrays.asList(fileSourceRoot, fileTestSourceRoot), Arrays.asList(fileRoot));
+ assertFalse(myFileIndex.isInContent(fileRoot));
+ assertFalse(myFileIndex.isInSource(fileRoot));
+ assertIteratedContent(myFileIndex, Arrays.asList(fileSourceRoot, fileTestSourceRoot), Arrays.asList(fileRoot));
}
private void assertIteratedContent(ProjectFileIndex fileIndex,
@@ -764,63 +780,57 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
public void testFileSourceRootsUnderDirContentRoot() throws IOException {
- ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
-
VirtualFile fileSourceRoot = myModule1Dir.createChildData(this, "fileSourceRoot.txt");
- assertTrue(fileIndex.isInContent(fileSourceRoot));
- assertFalse(fileIndex.isInSource(fileSourceRoot));
+ assertTrue(myFileIndex.isInContent(fileSourceRoot));
+ assertFalse(myFileIndex.isInSource(fileSourceRoot));
PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
- assertTrue(fileIndex.isInContent(fileSourceRoot));
- assertTrue(fileIndex.isInSource(fileSourceRoot));
+ assertTrue(myFileIndex.isInContent(fileSourceRoot));
+ assertTrue(myFileIndex.isInSource(fileSourceRoot));
checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
// removing file source root
PsiTestUtil.removeSourceRoot(myModule, fileSourceRoot);
- assertTrue(fileIndex.isInContent(fileSourceRoot));
- assertFalse(fileIndex.isInSource(fileSourceRoot));
+ assertTrue(myFileIndex.isInContent(fileSourceRoot));
+ assertFalse(myFileIndex.isInSource(fileSourceRoot));
}
public void testFileModuleExcludeRootUnderDirectoryRoot() throws IOException {
- ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
-
VirtualFile fileExcludeRoot = mySrcDir1.createChildData(this, "fileExcludeRoot.txt");
- assertTrue(fileIndex.isInContent(fileExcludeRoot));
- assertTrue(fileIndex.isInSource(fileExcludeRoot));
- assertIteratedContent(fileIndex, Arrays.asList(fileExcludeRoot), null);
+ assertTrue(myFileIndex.isInContent(fileExcludeRoot));
+ assertTrue(myFileIndex.isInSource(fileExcludeRoot));
+ assertIteratedContent(myFileIndex, Arrays.asList(fileExcludeRoot), null);
PsiTestUtil.addExcludedRoot(myModule, fileExcludeRoot);
- assertFalse(fileIndex.isInContent(fileExcludeRoot));
- assertFalse(fileIndex.isInSource(fileExcludeRoot));
+ assertFalse(myFileIndex.isInContent(fileExcludeRoot));
+ assertFalse(myFileIndex.isInSource(fileExcludeRoot));
assertExcluded(fileExcludeRoot, myModule);
- assertIteratedContent(fileIndex, null, Arrays.asList(fileExcludeRoot));
+ assertIteratedContent(myFileIndex, null, Arrays.asList(fileExcludeRoot));
// removing file exclude root
PsiTestUtil.removeExcludedRoot(myModule, fileExcludeRoot);
- assertTrue(fileIndex.isInContent(fileExcludeRoot));
- assertTrue(fileIndex.isInSource(fileExcludeRoot));
- assertIteratedContent(fileIndex, Arrays.asList(fileExcludeRoot), null);
+ assertTrue(myFileIndex.isInContent(fileExcludeRoot));
+ assertTrue(myFileIndex.isInSource(fileExcludeRoot));
+ assertIteratedContent(myFileIndex, Arrays.asList(fileExcludeRoot), null);
}
public void testFileModuleExcludeRootUnderFileRoot() throws IOException {
- ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
-
VirtualFile fileRoot = myRootVFile.createChildData(this, "fileRoot.txt");
PsiTestUtil.addContentRoot(myModule, fileRoot);
checkInfo(fileRoot, myModule, false, false, "", null);
- assertTrue(fileIndex.isInContent(fileRoot));
- assertIteratedContent(fileIndex, Arrays.asList(fileRoot), null);
+ assertTrue(myFileIndex.isInContent(fileRoot));
+ assertIteratedContent(myFileIndex, Arrays.asList(fileRoot), null);
PsiTestUtil.addExcludedRoot(myModule, fileRoot);
- assertFalse(fileIndex.isInContent(fileRoot));
+ assertFalse(myFileIndex.isInContent(fileRoot));
assertExcluded(fileRoot, myModule);
- assertIteratedContent(fileIndex, null, Arrays.asList(fileRoot));
+ assertIteratedContent(myFileIndex, null, Arrays.asList(fileRoot));
// removing file exclude root
PsiTestUtil.removeExcludedRoot(myModule, fileRoot);
checkInfo(fileRoot, myModule, false, false, "", null);
- assertTrue(fileIndex.isInContent(fileRoot));
- assertIteratedContent(fileIndex, Arrays.asList(fileRoot), null);
+ assertTrue(myFileIndex.isInContent(fileRoot));
+ assertIteratedContent(myFileIndex, Arrays.asList(fileRoot), null);
}
public void testFileLibraryInsideFolderLibrary() throws IOException {
@@ -835,8 +845,6 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
public void testFileContentRootsModifications() throws IOException {
- ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
-
VirtualFile temp = myRootVFile.createChildDirectory(this, "temp");
VirtualFile fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt");
@@ -845,54 +853,54 @@ public class DirectoryIndexTest extends IdeaTestCase {
PsiTestUtil.addContentRoot(myModule, fileSourceRoot);
PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
- assertTrue(fileIndex.isInContent(fileSourceRoot));
- assertTrue(fileIndex.isInSource(fileSourceRoot));
+ assertTrue(myFileIndex.isInContent(fileSourceRoot));
+ assertTrue(myFileIndex.isInSource(fileSourceRoot));
// delete and recreate
fileSourceRoot.delete(this);
assertNotInProject(fileSourceRoot);
- assertFalse(fileIndex.isInContent(fileSourceRoot));
- assertFalse(fileIndex.isInSource(fileSourceRoot));
+ assertFalse(myFileIndex.isInContent(fileSourceRoot));
+ assertFalse(myFileIndex.isInSource(fileSourceRoot));
fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt");
checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
- assertTrue(fileIndex.isInContent(fileSourceRoot));
- assertTrue(fileIndex.isInSource(fileSourceRoot));
+ assertTrue(myFileIndex.isInContent(fileSourceRoot));
+ assertTrue(myFileIndex.isInSource(fileSourceRoot));
// delete and move from another dir
fileSourceRoot.delete(this);
assertNotInProject(fileSourceRoot);
- assertFalse(fileIndex.isInContent(fileSourceRoot));
- assertFalse(fileIndex.isInSource(fileSourceRoot));
+ assertFalse(myFileIndex.isInContent(fileSourceRoot));
+ assertFalse(myFileIndex.isInSource(fileSourceRoot));
fileSourceRoot = temp.createChildData(this, "fileSourceRoot.txt");
assertNotInProject(fileSourceRoot);
fileSourceRoot.move(this, myRootVFile);
checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
- assertTrue(fileIndex.isInContent(fileSourceRoot));
- assertTrue(fileIndex.isInSource(fileSourceRoot));
+ assertTrue(myFileIndex.isInContent(fileSourceRoot));
+ assertTrue(myFileIndex.isInSource(fileSourceRoot));
// delete and copy from another dir
fileSourceRoot.delete(this);
assertNotInProject(fileSourceRoot);
- assertFalse(fileIndex.isInContent(fileSourceRoot));
- assertFalse(fileIndex.isInSource(fileSourceRoot));
+ assertFalse(myFileIndex.isInContent(fileSourceRoot));
+ assertFalse(myFileIndex.isInSource(fileSourceRoot));
fileSourceRoot = temp.createChildData(this, "fileSourceRoot.txt");
assertNotInProject(fileSourceRoot);
fileSourceRoot = fileSourceRoot.copy(this, myRootVFile, "fileSourceRoot.txt");
checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
- assertTrue(fileIndex.isInContent(fileSourceRoot));
- assertTrue(fileIndex.isInSource(fileSourceRoot));
+ assertTrue(myFileIndex.isInContent(fileSourceRoot));
+ assertTrue(myFileIndex.isInSource(fileSourceRoot));
// delete and rename from another file
fileSourceRoot.delete(this);
assertNotInProject(fileSourceRoot);
- assertFalse(fileIndex.isInContent(fileSourceRoot));
- assertFalse(fileIndex.isInSource(fileSourceRoot));
+ assertFalse(myFileIndex.isInContent(fileSourceRoot));
+ assertFalse(myFileIndex.isInSource(fileSourceRoot));
fileSourceRoot = myRootVFile.createChildData(this, "temp_file.txt");
assertNotInProject(fileSourceRoot);
fileSourceRoot.rename(this, "fileSourceRoot.txt");
checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
- assertTrue(fileIndex.isInContent(fileSourceRoot));
- assertTrue(fileIndex.isInSource(fileSourceRoot));
+ assertTrue(myFileIndex.isInContent(fileSourceRoot));
+ assertTrue(myFileIndex.isInSource(fileSourceRoot));
}
private void checkInfo(VirtualFile file,
@@ -914,15 +922,14 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertEquals(isInLibrary, info.hasLibraryClassRoot());
assertEquals(isInLibrarySource, info.isInLibrarySource());
- final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
if (file.isDirectory()) {
- assertEquals(packageName, fileIndex.getPackageNameByDirectory(file));
+ assertEquals(packageName, myFileIndex.getPackageNameByDirectory(file));
}
- assertEquals(Arrays.toString(info.getOrderEntries()), modulesOfOrderEntries.length, info.getOrderEntries().length);
+ assertEquals(Arrays.toString(myIndex.getOrderEntries(info)), modulesOfOrderEntries.length, myIndex.getOrderEntries(info).length);
for (Module aModule : modulesOfOrderEntries) {
- OrderEntry found = info.findOrderEntryWithOwnerModule(aModule);
- assertNotNull("not found: " + aModule + " in " + Arrays.toString(info.getOrderEntries()), found);
+ OrderEntry found = myIndex.findOrderEntryWithOwnerModule(info, aModule);
+ assertNotNull("not found: " + aModule + " in " + Arrays.toString(myIndex.getOrderEntries(info)), found);
}
}
@@ -941,7 +948,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
private DirectoryInfo assertInProject(VirtualFile file) {
DirectoryInfo info = myIndex.getInfoForFile(file);
assertTrue(file.toString(), info.isInProject());
- info.assertConsistency();
+ myIndex.assertConsistency(info);
return info;
}
@@ -957,6 +964,11 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile[] actualDirs = myIndex.getDirectoriesByPackageName(packageName, includeLibrarySources).toArray(VirtualFile.EMPTY_ARRAY);
assertNotNull(actualDirs);
assertOrderedEquals(actualDirs, expectedDirs);
+
+ for (VirtualFile dir : expectedDirs) {
+ String actualName = myIndex.getPackageName(dir);
+ assertEquals("Invalid package name for dir " + dir + ": " + packageName, packageName, actualName);
+ }
}
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java b/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java
index 096547c4f4db..61414ab0b416 100644
--- a/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java
@@ -260,4 +260,20 @@ public class MiscPsiTest extends LightCodeInsightFixtureTestCase {
assertEquals("some.unknown.Foo<? extends String>", type.getCanonicalText());
}
+ public void testNoPsiModificationsInUncommittedDocument() {
+ final PsiJavaFile file = (PsiJavaFile)myFixture.addFileToProject("a.java", "class A{}");
+ Document document = file.getViewProvider().getDocument();
+ document.insertString(0, " ");
+
+ PsiClass psiClass = file.getClasses()[0];
+ try {
+ psiClass.addBefore(PsiParserFacade.SERVICE.getInstance(getProject()).createWhiteSpaceFromText(" "), psiClass.getLBrace());
+ fail();
+ }
+ catch (IllegalStateException e) {
+ assertEquals("Attempt to modify PSI for non-committed Document!", e.getMessage());
+ }
+ assertEquals("class A{}", psiClass.getText());
+ assertEquals(" class A{}", document.getText());
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy
index d11a34f6e376..7b1861b9daec 100644
--- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy
@@ -385,4 +385,28 @@ public class test {
]
)
}
+
+ void "test IDEA-128071"() {
+ doTest(
+ initial: '''
+public class FormatTest {
+ public int a = 3;
+ private static final String FACEBOOK_CLIENT_ID = "";
+ public static final String FACEBOOK_OAUTH_URL = "".concat(FACEBOOK_CLIENT_ID).concat("");
+}
+''',
+ expected: '''
+public class FormatTest {
+ private static final String FACEBOOK_CLIENT_ID = "";
+ public static final String FACEBOOK_OAUTH_URL = "".concat(FACEBOOK_CLIENT_ID).concat("");
+ public int a = 3;
+}
+''',
+ rules: [
+ rule(PUBLIC, STATIC, FINAL),
+ rule(PRIVATE, STATIC, FINAL),
+ rule(PUBLIC)
+ ]
+ )
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java b/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java
index 204525cb6822..e830594db39f 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java
@@ -208,6 +208,10 @@ public class RenameCollisionsTest extends LightRefactoringTestCase {
doTest("foo2");
}
+ public void testRenameMethodNoCollisionWithOtherSignatureMethodRef() throws Exception {
+ doTest("foo2");
+ }
+
public void testRenameNoStaticOverridingInInterfaces() throws Exception {
doTest("foo");
}
diff --git a/java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java b/java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java
index 514348e5913b..0ad26a34eec5 100644
--- a/java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java
+++ b/java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java
@@ -105,15 +105,21 @@ public class ModuleScopesTest extends ModuleTestCase {
}
private Module addDependentModule(final Module moduleA, final DependencyScope scope) {
- final Module moduleB = createModule("b.iml", StdModuleTypes.JAVA);
+ return addDependentModule("b", moduleA, scope, false);
+ }
+
+ private Module addDependentModule(final String name, final Module moduleA,
+ final DependencyScope scope,
+ final boolean exported) {
+ final Module moduleB = createModule(name + ".iml", StdModuleTypes.JAVA);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
- VirtualFile rootB = myFixture.findOrCreateDir("b");
+ VirtualFile rootB = myFixture.findOrCreateDir(name);
VirtualFile outB = myFixture.findOrCreateDir("out");
- ModuleRootModificationUtil.addDependency(moduleA, moduleB, scope, false);
+ ModuleRootModificationUtil.addDependency(moduleA, moduleB, scope, exported);
PsiTestUtil.addSourceRoot(moduleB, rootB);
PsiTestUtil.setCompilerOutputPath(moduleB, outB.getUrl(), false);
@@ -123,6 +129,25 @@ public class ModuleScopesTest extends ModuleTestCase {
return moduleB;
}
+ public void testModuleTwiceInDependents() throws IOException {
+ Module m = createModule("m.iml", StdModuleTypes.JAVA);
+ Module a = createModule("a.iml", StdModuleTypes.JAVA);
+ Module b = createModule("b.iml", StdModuleTypes.JAVA);
+ Module c = createModule("c.iml", StdModuleTypes.JAVA);
+
+ ModuleRootModificationUtil.addDependency(a, m, DependencyScope.COMPILE, false);
+ ModuleRootModificationUtil.addDependency(b, m, DependencyScope.COMPILE, true);
+ ModuleRootModificationUtil.addDependency(a, b, DependencyScope.COMPILE, true);
+ ModuleRootModificationUtil.addDependency(c, a, DependencyScope.COMPILE, true);
+
+ VirtualFile root = myFixture.findOrCreateDir("c");
+ PsiTestUtil.addSourceContentToRoots(c, root);
+ VirtualFile file = root.createChildData(this, "x.txt");
+
+ GlobalSearchScope deps = m.getModuleWithDependentsScope();
+ assertTrue(deps.contains(file));
+ }
+
public void testTestOnlyLibraryDependency() throws IOException {
Module m = createModule("a.iml", StdModuleTypes.JAVA);
addLibrary(m, DependencyScope.TEST);
diff --git a/java/java-tests/testSrc/com/intellij/slicer/SliceTreeTest.java b/java/java-tests/testSrc/com/intellij/slicer/SliceTreeTest.java
index 6e34ebf5f939..b6d8840059ba 100644
--- a/java/java-tests/testSrc/com/intellij/slicer/SliceTreeTest.java
+++ b/java/java-tests/testSrc/com/intellij/slicer/SliceTreeTest.java
@@ -49,7 +49,8 @@ public class SliceTreeTest extends SliceTestCase {
SliceUsage usage = SliceUsage.createRootUsage(element, params);
- SlicePanel panel = new SlicePanel(getProject(), true, new SliceRootNode(getProject(), new DuplicateMap(), usage), false, ToolWindowHeadlessManagerImpl.HEADLESS_WINDOW) {
+ ToolWindowHeadlessManagerImpl.MockToolWindow toolWindow = new ToolWindowHeadlessManagerImpl.MockToolWindow(myProject);
+ SlicePanel panel = new SlicePanel(getProject(), true, new SliceRootNode(getProject(), new DuplicateMap(), usage), false, toolWindow) {
@Override
protected void close() {
}
diff --git a/java/jsp-openapi/src/com/intellij/psi/jsp/JavaJspElementVisitor.java b/java/jsp-openapi/src/com/intellij/psi/jsp/JavaJspElementVisitor.java
index 6eda197118bd..6100c98323bc 100644
--- a/java/jsp-openapi/src/com/intellij/psi/jsp/JavaJspElementVisitor.java
+++ b/java/jsp-openapi/src/com/intellij/psi/jsp/JavaJspElementVisitor.java
@@ -21,9 +21,6 @@ import com.intellij.psi.JavaElementVisitor;
* @author yole
*/
public abstract class JavaJspElementVisitor extends JavaElementVisitor {
- public void visitJspImplicitVariable(JspImplicitVariable variable){
- visitImplicitVariable(variable);
- }
public void visitJspFile(JspFile jspFile) {
visitFile(jspFile);
diff --git a/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java b/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java
index 05500e31ebd3..b93deafa1fe8 100644
--- a/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java
+++ b/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java
@@ -17,15 +17,20 @@
package com.intellij.ui.classFilter;
import com.intellij.openapi.diagnostic.Logger;
+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 Cloneable {
+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];
@@ -67,6 +72,16 @@ public class ClassFilter implements Cloneable {
return getPattern();
}
+ @Override
+ public void readExternal(Element element) throws InvalidDataException {
+ DefaultJDOMExternalizer.readExternal(this, element);
+ }
+
+ @Override
+ public void writeExternal(Element element) throws WriteExternalException {
+ DefaultJDOMExternalizer.writeExternal(this, element);
+ }
+
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ClassFilter)) return false;
diff --git a/java/remote-servers/impl/remote-servers-java-impl.iml b/java/remote-servers/impl/remote-servers-java-impl.iml
index 6999e2deac71..15781473aa45 100644
--- a/java/remote-servers/impl/remote-servers-java-impl.iml
+++ b/java/remote-servers/impl/remote-servers-java-impl.iml
@@ -15,6 +15,7 @@
<orderEntry type="module" module-name="remote-servers-impl" />
<orderEntry type="module" module-name="java-impl" />
<orderEntry type="module" module-name="openapi" />
+ <orderEntry type="module" module-name="idea-ui" />
</component>
</module>
diff --git a/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml b/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml
index 24a0776ccd29..692199e3bb2c 100644
--- a/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml
+++ b/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml
@@ -2,7 +2,7 @@
<extensionPoints>
<extensionPoint qualifiedName="com.intellij.remoteServer.moduleBuilderContribution"
- interface="com.intellij.remoteServer.impl.module.CloudModuleBuilderContribution"/>
+ interface="com.intellij.remoteServer.impl.module.CloudModuleBuilderContributionFactory"/>
</extensionPoints>
<extensions defaultExtensionNs="com.intellij">
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfigurable.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfigurable.java
index 14bd043a7f23..e235eeeb55aa 100644
--- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfigurable.java
+++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfigurable.java
@@ -15,152 +15,20 @@
*/
package com.intellij.remoteServer.impl.module;
-import com.intellij.openapi.Disposable;
import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Disposer;
import com.intellij.remoteServer.configuration.RemoteServer;
-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.remoteServer.util.*;
-import com.intellij.util.concurrency.Semaphore;
-import com.intellij.util.ui.UIUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
-import java.util.Collection;
-import java.util.concurrent.atomic.AtomicReference;
+import java.awt.*;
-public abstract class CloudApplicationConfigurable<
- SC extends CloudConfigurationBase,
- DC extends CloudDeploymentNameConfiguration,
- SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>,
- AC extends CloudApplicationConfiguration> {
+public abstract class CloudApplicationConfigurable {
- private final Project myProject;
- private final Disposable myParentDisposable;
+ public abstract Component getComponent();
- private DelayedRunner myRunner;
+ public abstract void setAccount(RemoteServer<?> account);
- private RemoteServer<?> myAccount;
-
- public CloudApplicationConfigurable(@Nullable Project project, Disposable parentDisposable) {
- myProject = project;
- myParentDisposable = parentDisposable;
- }
-
- public void setAccount(RemoteServer<?> account) {
- myAccount = account;
- clearCloudData();
- }
-
- protected RemoteServer<SC> getAccount() {
- return (RemoteServer<SC>)myAccount;
- }
-
- public JComponent getComponent() {
- JComponent result = getMainPanel();
- if (myRunner == null) {
- myRunner = new DelayedRunner(result) {
-
- private RemoteServer<?> myPreviousAccount;
-
- @Override
- protected boolean wasChanged() {
- boolean result = myPreviousAccount != myAccount;
- if (result) {
- myPreviousAccount = myAccount;
- }
- return result;
- }
-
- @Override
- protected void run() {
- loadCloudData();
- }
- };
- Disposer.register(myParentDisposable, myRunner);
- }
- return result;
- }
-
- protected void clearCloudData() {
- getExistingComboBox().removeAllItems();
- }
-
- protected void loadCloudData() {
- new ConnectionTask<Collection<Deployment>>("Loading existing applications list") {
-
- @Override
- protected void run(final ServerConnection<DC> connection,
- final Semaphore semaphore,
- final AtomicReference<Collection<Deployment>> result) {
- connection.connectIfNeeded(new ServerConnector.ConnectionCallback<DC>() {
-
- @Override
- public void connected(@NotNull ServerRuntimeInstance<DC> serverRuntimeInstance) {
- connection.computeDeployments(new Runnable() {
-
- @Override
- public void run() {
- result.set(connection.getDeployments());
- semaphore.up();
- UIUtil.invokeLaterIfNeeded(new Runnable() {
- @Override
- public void run() {
- if (!Disposer.isDisposed(myParentDisposable)) {
- setupExistingApplications(result.get());
- }
- }
- });
- }
- });
- }
-
- @Override
- public void errorOccurred(@NotNull String errorMessage) {
- runtimeErrorOccurred(errorMessage);
- semaphore.up();
- }
- });
- }
-
- @Override
- protected Collection<Deployment> run(SR serverRuntimeInstance) throws ServerRuntimeException {
- return null;
- }
- }.performAsync();
- }
-
- private void setupExistingApplications(Collection<Deployment> deployments) {
- JComboBox existingComboBox = getExistingComboBox();
- existingComboBox.removeAllItems();
- for (Deployment deployment : deployments) {
- existingComboBox.addItem(deployment.getName());
- }
- }
-
- protected Project getProject() {
- return myProject;
- }
-
- protected abstract JComboBox getExistingComboBox();
-
- protected abstract JComponent getMainPanel();
-
- public abstract AC createConfiguration();
+ public abstract CloudApplicationConfiguration createConfiguration();
public abstract void validate() throws ConfigurationException;
-
- protected abstract class ConnectionTask<T> extends CloudConnectionTask<T, SC, DC, SR> {
-
- public ConnectionTask(String title) {
- super(myProject, title, CloudApplicationConfigurable.this.getAccount());
- }
- }
}
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfiguration.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfiguration.java
index 9af0f1ad472b..af9fa723e82a 100644
--- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfiguration.java
+++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfiguration.java
@@ -18,19 +18,4 @@ package com.intellij.remoteServer.impl.module;
public abstract class CloudApplicationConfiguration {
- private boolean myExisting;
- private final String myExistingAppName;
-
- protected CloudApplicationConfiguration(boolean existing, String existingAppName) {
- myExisting = existing;
- myExistingAppName = existingAppName;
- }
-
- public boolean isExisting() {
- return myExisting;
- }
-
- public String getExistingAppName() {
- return myExistingAppName;
- }
}
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java
index 4aa8d60bcea4..62e256c14c8e 100644
--- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java
+++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java
@@ -16,6 +16,7 @@
package com.intellij.remoteServer.impl.module;
import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase;
import com.intellij.ide.util.projectWizard.JavaModuleBuilder;
import com.intellij.ide.util.projectWizard.ModuleBuilderListener;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
@@ -23,20 +24,42 @@ import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.module.JavaModuleType;
import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
+import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
+import com.intellij.util.containers.hash.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.util.Map;
public class CloudModuleBuilder extends JavaModuleBuilder {
private RemoteServer<?> myAccount;
private CloudApplicationConfiguration myApplicationConfiguration;
+ private FrameworkSupportModelBase myFrameworkSupportModel;
+
+ private Map<ServerType<?>, CloudModuleBuilderContribution> myCloudType2Contribution;
+ private Project myProject;
public CloudModuleBuilder() {
+ myCloudType2Contribution = new HashMap<ServerType<?>, CloudModuleBuilderContribution>();
+
+ ModuleConfigurationUpdater configurationUpdater = new ModuleConfigurationUpdater() {
+
+ public void update(@NotNull final Module module, @NotNull final ModifiableRootModel rootModel) {
+ preConfigureModule(module, rootModel);
+ }
+ };
+ addModuleConfigurationUpdater(configurationUpdater);
+
addListener(new ModuleBuilderListener() {
@Override
@@ -93,7 +116,8 @@ public class CloudModuleBuilder extends JavaModuleBuilder {
@Nullable
@Override
public ModuleWizardStep getCustomOptionsStep(WizardContext context, Disposable parentDisposable) {
- return new CloudModuleWizardStep(this, context.getProject(), parentDisposable);
+ myProject = context.getProject();
+ return new CloudModuleWizardStep(this, myProject, parentDisposable);
}
public void setAccount(RemoteServer<?> account) {
@@ -108,7 +132,43 @@ public class CloudModuleBuilder extends JavaModuleBuilder {
myApplicationConfiguration = applicationConfiguration;
}
+ public CloudApplicationConfiguration getApplicationConfiguration() {
+ return myApplicationConfiguration;
+ }
+
+ public CloudModuleBuilderContribution getContribution(ServerType<?> cloudType) {
+ CloudModuleBuilderContribution result = myCloudType2Contribution.get(cloudType);
+ if (result == null) {
+ result = CloudModuleBuilderContributionFactory.getInstanceByType(cloudType).createContribution(this);
+ myCloudType2Contribution.put(cloudType, result);
+ }
+ return result;
+ }
+
+ private CloudModuleBuilderContribution getContribution() {
+ return getContribution(myAccount.getType());
+ }
+
+ private void preConfigureModule(Module module, ModifiableRootModel model) {
+ getContribution().preConfigureModule(module, model);
+ }
+
private void configureModule(final Module module) {
- CloudModuleBuilderContribution.getInstanceByType(myAccount.getType()).configureModule(module, myAccount, myApplicationConfiguration);
+ getContribution().configureModule(module);
+ }
+
+ public FrameworkSupportModelBase getFrameworkSupportModel() {
+ if (myFrameworkSupportModel == null) {
+ final LibrariesContainer librariesContainer = LibrariesContainerFactory.createContainer(myProject);
+ myFrameworkSupportModel = new FrameworkSupportModelBase(myProject, this, librariesContainer) {
+
+ @NotNull
+ @Override
+ public String getBaseDirectoryForLibrariesPath() {
+ return StringUtil.notNullize(getContentEntryPath());
+ }
+ };
+ }
+ return myFrameworkSupportModel;
}
}
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContribution.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContribution.java
index 6643c89cc1c4..dd2d9d9af563 100644
--- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContribution.java
+++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContribution.java
@@ -16,33 +16,51 @@
package com.intellij.remoteServer.impl.module;
import com.intellij.openapi.Disposable;
-import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.remoteServer.ServerType;
-import com.intellij.remoteServer.configuration.RemoteServer;
+import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
+import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
import org.jetbrains.annotations.Nullable;
public abstract class CloudModuleBuilderContribution {
- public static final ExtensionPointName<CloudModuleBuilderContribution> EP_NAME
- = ExtensionPointName.create("com.intellij.remoteServer.moduleBuilderContribution");
+ private final CloudModuleBuilder myModuleBuilder;
- public abstract ServerType<?> getCloudType();
+ private final ServerType<?> myCloudType;
+ private CloudApplicationConfigurable myApplicationConfigurable;
- public abstract CloudApplicationConfigurable createApplicationConfigurable(@Nullable Project project, Disposable parentDisposable);
+ public CloudModuleBuilderContribution(CloudModuleBuilder moduleBuilder, ServerType<?> cloudType) {
+ myModuleBuilder = moduleBuilder;
+ myCloudType = cloudType;
+ }
+
+ protected CloudModuleBuilder getModuleBuilder() {
+ return myModuleBuilder;
+ }
- public abstract void configureModule(Module module,
- RemoteServer<?> account,
- CloudApplicationConfiguration configuration);
+ protected ServerType<?> getCloudType() {
+ return myCloudType;
+ }
- public static CloudModuleBuilderContribution getInstanceByType(ServerType<?> cloudType) {
- for (CloudModuleBuilderContribution contribution : EP_NAME.getExtensions()) {
- if (contribution.getCloudType() == cloudType) {
- return contribution;
- }
+ public CloudApplicationConfigurable getApplicationConfigurable(@Nullable Project project, Disposable parentDisposable) {
+ if (myApplicationConfigurable == null) {
+ myApplicationConfigurable = createApplicationConfigurable(project, parentDisposable);
}
- return null;
+ return myApplicationConfigurable;
+ }
+
+ public void preConfigureModule(Module module, ModifiableRootModel model) {
+
+ }
+
+ public abstract void configureModule(Module module);
+
+ protected abstract CloudApplicationConfigurable createApplicationConfigurable(@Nullable Project project, Disposable parentDisposable);
+
+ protected DeploymentConfiguration createDeploymentConfiguration(DeploymentSource deploymentSource) {
+ return myCloudType.createDeploymentConfigurator(null).createDefaultConfiguration(deploymentSource);
}
}
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionBase.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionBase.java
deleted file mode 100644
index 6a927d97bb93..000000000000
--- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionBase.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.remoteServer.impl.module;
-
-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.module.Module;
-import com.intellij.openapi.module.ModulePointer;
-import com.intellij.openapi.module.ModulePointerManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.MessageType;
-import com.intellij.remoteServer.ServerType;
-import com.intellij.remoteServer.configuration.RemoteServer;
-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.util.*;
-import com.intellij.remoteServer.util.ssh.SshKeyChecker;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-
-public abstract class CloudModuleBuilderContributionBase<
- SC extends CloudConfigurationBase,
- DC extends CloudDeploymentNameConfiguration,
- AC extends CloudApplicationConfiguration,
- SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>>
- extends CloudModuleBuilderContribution {
-
- @Override
- public void configureModule(Module module,
- RemoteServer<?> account,
- CloudApplicationConfiguration applicationConfiguration) {
- RemoteServer<SC> castedAccount = (RemoteServer<SC>)account;
- final AC castedApplicationConfiguration = (AC)applicationConfiguration;
-
- DC deploymentConfiguration = createDeploymentConfiguration();
-
- if (applicationConfiguration.isExisting()) {
- deploymentConfiguration.setDefaultDeploymentName(false);
- deploymentConfiguration.setDeploymentName(applicationConfiguration.getExistingAppName());
- }
-
- final DeployToServerRunConfiguration<SC, DC> runConfiguration = createRunConfiguration(module, castedAccount, deploymentConfiguration);
-
- final String cloudName = account.getType().getPresentableName();
- final Project project = module.getProject();
- new CloudConnectionTask<Object, SC, DC, SR>(project, CloudBundle.getText("cloud.support", cloudName), castedAccount) {
-
- CloudNotifier myNotifier = new CloudNotifier(cloudName);
-
- boolean myFirstAttempt = true;
-
- @Override
- protected Object run(SR serverRuntime) throws ServerRuntimeException {
- doConfigureModule(castedApplicationConfiguration, runConfiguration, myFirstAttempt, serverRuntime);
- myNotifier.showMessage(CloudBundle.getText("cloud.support.added", cloudName), MessageType.INFO);
- return null;
- }
-
- @Override
- protected void runtimeErrorOccurred(@NotNull String errorMessage) {
- myFirstAttempt = false;
- new SshKeyChecker().checkServerError(errorMessage, myNotifier, project, this);
- }
- }.performAsync();
- }
-
- private DeployToServerRunConfiguration<SC, DC> createRunConfiguration(Module module,
- RemoteServer<SC> server,
- DC deploymentConfiguration) {
- Project project = module.getProject();
-
- 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();
-
- result.setServerName(serverName);
-
- final ModulePointer modulePointer = ModulePointerManager.getInstance(project).create(module);
- result.setDeploymentSource(new ModuleDeploymentSourceImpl(modulePointer));
-
- result.setDeploymentConfiguration(deploymentConfiguration);
-
- runManager.addConfiguration(runSettings, false);
- runManager.setSelectedConfiguration(runSettings);
-
- return result;
- }
-
- private static String generateRunConfigurationName(String serverName, String moduleName) {
- return CloudBundle.getText("run.configuration.name", serverName, moduleName);
- }
-
- private DeployToServerConfigurationType getRunConfigurationType() {
- String id = DeployToServerConfigurationType.getId(getCloudType());
- 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;
- }
-
- @Override
- public abstract ServerType<SC> getCloudType();
-
- @Override
- public abstract CloudApplicationConfigurable<SC, DC, SR, AC> createApplicationConfigurable(@Nullable Project project,
- Disposable parentDisposable);
-
- protected abstract DC createDeploymentConfiguration();
-
- protected abstract void doConfigureModule(AC applicationConfiguration,
- DeployToServerRunConfiguration<SC, DC> runConfiguration,
- boolean firstAttempt,
- SR serverRuntime) throws ServerRuntimeException;
-}
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionFactory.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionFactory.java
new file mode 100644
index 000000000000..20ebc29fe148
--- /dev/null
+++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionFactory.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.remoteServer.impl.module;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.remoteServer.ServerType;
+
+
+public abstract class CloudModuleBuilderContributionFactory {
+
+ public static final ExtensionPointName<CloudModuleBuilderContributionFactory> EP_NAME
+ = ExtensionPointName.create("com.intellij.remoteServer.moduleBuilderContribution");
+
+ public abstract ServerType<?> getCloudType();
+
+ public abstract CloudModuleBuilderContribution createContribution(CloudModuleBuilder moduleBuilder);
+
+ public static CloudModuleBuilderContributionFactory getInstanceByType(ServerType<?> cloudType) {
+ for (CloudModuleBuilderContributionFactory contribution : EP_NAME.getExtensions()) {
+ if (contribution.getCloudType() == cloudType) {
+ return contribution;
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderSourceContribution.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderSourceContribution.java
new file mode 100644
index 000000000000..b5fdcc3995c8
--- /dev/null
+++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderSourceContribution.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.impl.module;
+
+import com.intellij.ide.util.newProjectWizard.StepSequence;
+import com.intellij.ide.util.newProjectWizard.modes.CreateFromSourcesMode;
+import com.intellij.ide.util.projectWizard.AbstractStepWithProgress;
+import com.intellij.ide.util.projectWizard.ModuleWizardStep;
+import com.intellij.ide.util.projectWizard.ProjectBuilder;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.module.Module;
+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.roots.ui.configuration.DefaultModulesProvider;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.remoteServer.ServerType;
+import com.intellij.remoteServer.configuration.RemoteServer;
+import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
+import com.intellij.remoteServer.util.*;
+import com.intellij.remoteServer.util.ssh.SshKeyChecker;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+
+public abstract class CloudModuleBuilderSourceContribution<
+ SC extends CloudConfigurationBase,
+ DC extends CloudDeploymentNameConfiguration,
+ AC extends CloudSourceApplicationConfiguration,
+ SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>>
+ extends CloudModuleBuilderContribution {
+
+ private CloudNotifier myNotifier;
+
+ public CloudModuleBuilderSourceContribution(CloudModuleBuilder moduleBuilder, ServerType<SC> cloudType) {
+ super(moduleBuilder, cloudType);
+ }
+
+ @Override
+ public void configureModule(final Module module) {
+ final CloudModuleBuilder moduleBuilder = getModuleBuilder();
+ RemoteServer<SC> account = (RemoteServer<SC>)moduleBuilder.getAccount();
+ final AC applicationConfiguration = (AC)moduleBuilder.getApplicationConfiguration();
+
+ DC deploymentConfiguration = createDeploymentConfiguration();
+
+ if (applicationConfiguration.isExisting()) {
+ deploymentConfiguration.setDefaultDeploymentName(false);
+ deploymentConfiguration.setDeploymentName(applicationConfiguration.getExistingAppName());
+ }
+
+ final DeployToServerRunConfiguration<SC, DC> runConfiguration
+ = CloudRunConfigurationUtil.createRunConfiguration(account, module, deploymentConfiguration);
+
+ final ServerType<?> cloudType = account.getType();
+ final Project project = module.getProject();
+ new CloudConnectionTask<Object, SC, DC, SR>(project,
+ CloudBundle.getText("cloud.support", cloudType.getPresentableName()),
+ account) {
+
+ boolean myFirstAttempt = true;
+
+ @Override
+ protected Object run(SR serverRuntime) throws ServerRuntimeException {
+ doConfigureModule(applicationConfiguration, runConfiguration, myFirstAttempt, serverRuntime);
+ return null;
+ }
+
+ @Override
+ protected void runtimeErrorOccurred(@NotNull String errorMessage) {
+ myFirstAttempt = false;
+ new SshKeyChecker().checkServerError(errorMessage, getNotifier(), project, this);
+ }
+
+ @Override
+ protected void postPerform(Object result) {
+ detectModuleStructure(module, moduleBuilder.getContentEntryPath());
+ }
+
+ @Override
+ protected boolean shouldStartInBackground() {
+ return false;
+ }
+ }.performAsync();
+ }
+
+ private CloudNotifier getNotifier() {
+ if (myNotifier == null) {
+ myNotifier = new CloudNotifier(getCloudType().getPresentableName());
+ }
+ return myNotifier;
+ }
+
+ private void detectModuleStructure(Module module, final String contentPath) {
+ final Project project = module.getProject();
+
+ final CreateFromSourcesMode mode = new CreateFromSourcesMode() {
+
+ @Override
+ public boolean isAvailable(WizardContext context) {
+ return true;
+ }
+
+ @Override
+ public void addSteps(WizardContext context, ModulesProvider modulesProvider, StepSequence sequence, String specific) {
+ super.addSteps(context, modulesProvider, sequence, specific);
+ myProjectBuilder.setFileToImport(contentPath);
+ }
+ };
+
+ final WizardContext context = new WizardContext(project);
+
+ final StepSequence stepSequence = mode.getSteps(context, DefaultModulesProvider.createForProject(context.getProject()));
+ if (stepSequence == null) {
+ return;
+ }
+
+ Disposer.register(project, new Disposable() {
+
+ @Override
+ public void dispose() {
+ for (ModuleWizardStep step : stepSequence.getAllSteps()) {
+ step.disposeUIResources();
+ }
+ }
+ });
+
+ ProgressManager.getInstance()
+ .run(new Task.Backgroundable(project, CloudBundle.getText("detect.module.structure", getCloudType().getPresentableName()), false) {
+
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ for (ModuleWizardStep step = ContainerUtil.getFirstItem(stepSequence.getSelectedSteps());
+ step != null;
+ step = stepSequence.getNextStep(step)) {
+ if (step instanceof AbstractStepWithProgress<?>) {
+ ((AbstractStepWithProgress)step).performStep();
+ }
+ else {
+ step.updateDataModel();
+ }
+ }
+ CloudAccountSelectionEditor.unsetAccountOnContext(context, getCloudType());
+ }
+
+ @Override
+ public boolean shouldStartInBackground() {
+ return false;
+ }
+
+ @Override
+ public void onSuccess() {
+ ProjectBuilder moduleBuilder = mode.getModuleBuilder();
+ if (moduleBuilder == null) {
+ return;
+ }
+ moduleBuilder.commit(project);
+ getNotifier().showMessage(CloudBundle.getText("cloud.support.added", getCloudType().getPresentableName()), MessageType.INFO);
+ }
+ });
+ }
+
+ @Override
+ protected abstract CloudSourceApplicationConfigurable<SC, DC, SR, AC> createApplicationConfigurable(@Nullable Project project,
+ Disposable parentDisposable);
+
+ protected abstract DC createDeploymentConfiguration();
+
+ protected abstract void doConfigureModule(AC applicationConfiguration,
+ DeployToServerRunConfiguration<SC, DC> runConfiguration,
+ boolean firstAttempt,
+ SR serverRuntime) throws ServerRuntimeException;
+}
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.java
index cf0e283616b2..79b307b0658e 100644
--- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.java
+++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.java
@@ -22,13 +22,13 @@ import com.intellij.openapi.project.Project;
import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.util.CloudAccountSelectionEditor;
-import com.intellij.util.containers.hash.HashMap;
+import com.intellij.util.containers.HashSet;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
+import java.util.Set;
public class CloudModuleWizardStep extends ModuleWizardStep {
@@ -43,17 +43,17 @@ public class CloudModuleWizardStep extends ModuleWizardStep {
private CloudAccountSelectionEditor myAccountSelectionPanel;
- private Map<ServerType<?>, CloudApplicationConfigurable> myCloudType2ApplicationConfigurable;
+ private Set<ServerType<?>> myApplicationConfigurableTypes;
public CloudModuleWizardStep(CloudModuleBuilder moduleBuilder, Project project, Disposable parentDisposable) {
myModuleBuilder = moduleBuilder;
myProject = project;
myParentDisposable = parentDisposable;
- myCloudType2ApplicationConfigurable = new HashMap<ServerType<?>, CloudApplicationConfigurable>();
+ myApplicationConfigurableTypes = new HashSet<ServerType<?>>();
List<ServerType<?>> cloudTypes = new ArrayList<ServerType<?>>();
- for (CloudModuleBuilderContribution contribution : CloudModuleBuilderContribution.EP_NAME.getExtensions()) {
+ for (CloudModuleBuilderContributionFactory contribution : CloudModuleBuilderContributionFactory.EP_NAME.getExtensions()) {
cloudTypes.add(contribution.getCloudType());
}
@@ -86,11 +86,8 @@ public class CloudModuleWizardStep extends ModuleWizardStep {
ServerType<?> cloudType = account.getType();
String cardName = cloudType.getId();
- CloudApplicationConfigurable<?, ?, ?, ?> applicationConfigurable = getApplicationConfigurable();
- if (applicationConfigurable == null) {
- applicationConfigurable
- = CloudModuleBuilderContribution.getInstanceByType(cloudType).createApplicationConfigurable(myProject, myParentDisposable);
- myCloudType2ApplicationConfigurable.put(cloudType, applicationConfigurable);
+ CloudApplicationConfigurable applicationConfigurable = getApplicationConfigurable();
+ if (myApplicationConfigurableTypes.add(cloudType)) {
myApplicationPanelPlaceHolder.add(applicationConfigurable.getComponent(), cardName);
}
applicationPlaceHolderLayout.show(myApplicationPanelPlaceHolder, cardName);
@@ -103,25 +100,25 @@ public class CloudModuleWizardStep extends ModuleWizardStep {
return myMainPanel;
}
- private CloudApplicationConfigurable<?, ?, ?, ?> getApplicationConfigurable() {
+ private CloudApplicationConfigurable getApplicationConfigurable() {
RemoteServer<?> account = getSelectedAccount();
if (account == null) {
return null;
}
- return myCloudType2ApplicationConfigurable.get(account.getType());
+ return myModuleBuilder.getContribution(account.getType()).getApplicationConfigurable(myProject, myParentDisposable);
}
@Override
public void updateDataModel() {
myModuleBuilder.setAccount(myAccountSelectionPanel.getSelectedAccount());
- CloudApplicationConfigurable<?, ?, ?, ?> configurable = getApplicationConfigurable();
+ CloudApplicationConfigurable configurable = getApplicationConfigurable();
myModuleBuilder.setApplicationConfiguration(configurable == null ? null : configurable.createConfiguration());
}
@Override
public boolean validate() throws ConfigurationException {
myAccountSelectionPanel.validate();
- CloudApplicationConfigurable<?, ?, ?, ?> configurable = getApplicationConfigurable();
+ CloudApplicationConfigurable configurable = getApplicationConfigurable();
if (configurable != null) {
configurable.validate();
}
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfigurable.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfigurable.java
new file mode 100644
index 000000000000..b6e0dfc857b0
--- /dev/null
+++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfigurable.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.impl.module;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.remoteServer.configuration.RemoteServer;
+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.remoteServer.util.*;
+import com.intellij.util.concurrency.Semaphore;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.Collection;
+import java.util.concurrent.atomic.AtomicReference;
+
+
+public abstract class CloudSourceApplicationConfigurable<
+ SC extends CloudConfigurationBase,
+ DC extends CloudDeploymentNameConfiguration,
+ SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>,
+ AC extends CloudApplicationConfiguration> extends CloudApplicationConfigurable {
+
+ private final Project myProject;
+ private final Disposable myParentDisposable;
+
+ private DelayedRunner myRunner;
+
+ private RemoteServer<?> myAccount;
+
+ public CloudSourceApplicationConfigurable(@Nullable Project project, Disposable parentDisposable) {
+ myProject = project;
+ myParentDisposable = parentDisposable;
+ }
+
+ @Override
+ public void setAccount(RemoteServer<?> account) {
+ myAccount = account;
+ clearCloudData();
+ }
+
+ protected RemoteServer<SC> getAccount() {
+ return (RemoteServer<SC>)myAccount;
+ }
+
+ @Override
+ public JComponent getComponent() {
+ JComponent result = getMainPanel();
+ if (myRunner == null) {
+ myRunner = new DelayedRunner(result) {
+
+ private RemoteServer<?> myPreviousAccount;
+
+ @Override
+ protected boolean wasChanged() {
+ boolean result = myPreviousAccount != myAccount;
+ if (result) {
+ myPreviousAccount = myAccount;
+ }
+ return result;
+ }
+
+ @Override
+ protected void run() {
+ loadCloudData();
+ }
+ };
+ Disposer.register(myParentDisposable, myRunner);
+ }
+ return result;
+ }
+
+ protected void clearCloudData() {
+ getExistingComboBox().removeAllItems();
+ }
+
+ protected void loadCloudData() {
+ new ConnectionTask<Collection<Deployment>>("Loading existing applications list") {
+
+ @Override
+ protected void run(final ServerConnection<DC> connection,
+ final Semaphore semaphore,
+ final AtomicReference<Collection<Deployment>> result) {
+ connection.connectIfNeeded(new ServerConnector.ConnectionCallback<DC>() {
+
+ @Override
+ public void connected(@NotNull ServerRuntimeInstance<DC> serverRuntimeInstance) {
+ connection.computeDeployments(new Runnable() {
+
+ @Override
+ public void run() {
+ result.set(connection.getDeployments());
+ semaphore.up();
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ if (!Disposer.isDisposed(myParentDisposable)) {
+ setupExistingApplications(result.get());
+ }
+ }
+ });
+ }
+ });
+ }
+
+ @Override
+ public void errorOccurred(@NotNull String errorMessage) {
+ runtimeErrorOccurred(errorMessage);
+ semaphore.up();
+ }
+ });
+ }
+
+ @Override
+ protected Collection<Deployment> run(SR serverRuntimeInstance) throws ServerRuntimeException {
+ return null;
+ }
+ }.performAsync();
+ }
+
+ private void setupExistingApplications(Collection<Deployment> deployments) {
+ JComboBox existingComboBox = getExistingComboBox();
+ existingComboBox.removeAllItems();
+ for (Deployment deployment : deployments) {
+ existingComboBox.addItem(deployment.getName());
+ }
+ }
+
+ protected Project getProject() {
+ return myProject;
+ }
+
+ protected abstract JComboBox getExistingComboBox();
+
+ protected abstract JComponent getMainPanel();
+
+ @Override
+ public abstract AC createConfiguration();
+
+ protected abstract class ConnectionTask<T> extends CloudConnectionTask<T, SC, DC, SR> {
+
+ public ConnectionTask(String title) {
+ super(myProject, title, CloudSourceApplicationConfigurable.this.getAccount());
+ }
+ }
+}
diff --git a/java/jsp-openapi/src/com/intellij/psi/jsp/JspImplicitVariable.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfiguration.java
index 921cc8055dd1..b1a3df6099ab 100644
--- a/java/jsp-openapi/src/com/intellij/psi/jsp/JspImplicitVariable.java
+++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfiguration.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,18 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.psi.jsp;
+package com.intellij.remoteServer.impl.module;
-import com.intellij.pom.Navigatable;
-import com.intellij.psi.ImplicitVariable;
-import com.intellij.psi.PsiElement;
-import com.intellij.navigation.NavigationItem;
-public interface JspImplicitVariable extends ImplicitVariable, NavigationItem {
- JspImplicitVariable[] EMPTY_ARRAY = new JspImplicitVariable[0];
- int INSIDE = 1;
- int AFTER = 2;
- int getDeclarationRange();
+public abstract class CloudSourceApplicationConfiguration extends CloudApplicationConfiguration {
- PsiElement getDeclaration();
-} \ No newline at end of file
+ private boolean myExisting;
+ private final String myExistingAppName;
+
+ protected CloudSourceApplicationConfiguration(boolean existing, String existingAppName) {
+ myExisting = existing;
+ myExistingAppName = existingAppName;
+ }
+
+ public boolean isExisting() {
+ return myExisting;
+ }
+
+ public String getExistingAppName() {
+ return myExistingAppName;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java b/java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java
index 49db796244dd..7e3c5f9cd55d 100644
--- a/java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java
+++ b/java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java
@@ -184,23 +184,24 @@ public abstract class DescriptorTestCase extends DebuggerTestCase {
for(int i = 0; i < tree.getRowCount(); i++) {
final TreeNode treeNode = (TreeNode)tree.getPathForRow(i).getLastPathComponent();
if(tree.isCollapsed(i) && !treeNode.isLeaf()) {
+ NodeDescriptor nodeDescriptor = null;
if (treeNode instanceof DebuggerTreeNodeImpl) {
- final NodeDescriptor nodeDescriptor = ((DebuggerTreeNodeImpl)treeNode).getDescriptor();
- boolean shouldExpand = filter == null || filter.shouldExpand(treeNode);
- if (shouldExpand) {
- // additional checks to prevent infinite expand
- if (nodeDescriptor instanceof ValueDescriptor) {
- final Value value = ((ValueDescriptor)nodeDescriptor).getValue();
- shouldExpand = !alreadyExpanded.contains(value);
- if (shouldExpand) {
- alreadyExpanded.add(value);
- }
+ nodeDescriptor = ((DebuggerTreeNodeImpl)treeNode).getDescriptor();
+ }
+ boolean shouldExpand = filter == null || filter.shouldExpand(treeNode);
+ if (shouldExpand) {
+ // additional checks to prevent infinite expand
+ if (nodeDescriptor instanceof ValueDescriptor) {
+ final Value value = ((ValueDescriptor)nodeDescriptor).getValue();
+ shouldExpand = !alreadyExpanded.contains(value);
+ if (shouldExpand) {
+ alreadyExpanded.add(value);
}
}
- if (shouldExpand) {
- anyCollapsed = true;
- tree.expandRow(i);
- }
+ }
+ if (shouldExpand) {
+ anyCollapsed = true;
+ tree.expandRow(i);
}
}
}
diff --git a/java/testFramework/src/com/intellij/find/FindManagerTestUtils.java b/java/testFramework/src/com/intellij/find/FindManagerTestUtils.java
index 087180bbc9a3..b65b58b8638c 100644
--- a/java/testFramework/src/com/intellij/find/FindManagerTestUtils.java
+++ b/java/testFramework/src/com/intellij/find/FindManagerTestUtils.java
@@ -24,12 +24,10 @@ public class FindManagerTestUtils {
}
public static void runFindInCommentsAndLiterals(FindManager findManager, FindModel findModel, String text, String ext) {
- findModel.setInStringLiteralsOnly(true);
- findModel.setInCommentsOnly(false);
+ findModel.setSearchContext(FindModel.SearchContext.IN_STRING_LITERALS);
runFindForwardAndBackward(findManager, findModel, text, ext);
- findModel.setInStringLiteralsOnly(false);
- findModel.setInCommentsOnly(true);
+ findModel.setSearchContext(FindModel.SearchContext.IN_COMMENTS);
runFindForwardAndBackward(findManager, findModel, text, ext);
}